Browse Source

Initial code for internal transport (GUI option internal vs jack)

tags/1.9.4
falkTX 12 years ago
parent
commit
f27c1ac362
27 changed files with 469 additions and 89 deletions
  1. +135
    -1
      resources/ui/carla.ui
  2. +38
    -23
      source/backend/CarlaBackend.hpp
  3. +21
    -1
      source/backend/CarlaEngine.hpp
  4. +1
    -1
      source/backend/CarlaPlugin.hpp
  5. +4
    -0
      source/backend/CarlaStandalone.hpp
  6. +34
    -0
      source/backend/engine/CarlaEngine.cpp
  7. +9
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  8. +31
    -1
      source/backend/engine/CarlaEngineJack.cpp
  9. +0
    -4
      source/backend/engine/CarlaEngineRtAudio.cpp
  10. +1
    -1
      source/backend/engine/Makefile
  11. +1
    -1
      source/backend/plugin/CarlaPlugin.cpp
  12. +3
    -3
      source/backend/plugin/DssiPlugin.cpp
  13. +3
    -3
      source/backend/plugin/FluidSynthPlugin.cpp
  14. +3
    -3
      source/backend/plugin/LadspaPlugin.cpp
  15. +3
    -3
      source/backend/plugin/LinuxSamplerPlugin.cpp
  16. +6
    -6
      source/backend/plugin/Lv2Plugin.cpp
  17. +1
    -1
      source/backend/plugin/Makefile
  18. +3
    -3
      source/backend/plugin/NativePlugin.cpp
  19. +4
    -4
      source/backend/plugin/VstPlugin.cpp
  20. +42
    -5
      source/backend/standalone/CarlaStandalone.cpp
  21. +1
    -1
      source/backend/standalone/Makefile
  22. +47
    -0
      source/carla.py
  23. +18
    -0
      source/carla_backend.py
  24. +29
    -24
      source/carla_shared.py
  25. +23
    -0
      source/libs/jackbridge/jackbridge.c
  26. +6
    -0
      source/libs/jackbridge/jackbridge.h
  27. +2
    -0
      source/utils/CarlaBackendUtils.hpp

+ 135
- 1
resources/ui/carla.ui View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>756</width>
<height>218</height>
<height>283</height>
</rect>
</property>
<property name="windowTitle">
@@ -15,6 +15,140 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QFrame" name="frame_transport">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Transport Mode:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="ch_transport"/>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_transport_play">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/16x16/media-playback-start.png</normaloff>:/16x16/media-playback-start.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_transport_stop">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/16x16/media-playback-stop.png</normaloff>:/16x16/media-playback-stop.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_transport_back">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="b_transport_forward">
<property name="maximumSize">
<size>
<width>22</width>
<height>22</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_time">
<property name="text">
<string>TIME (TODO)</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="w_plugins" native="true">
<layout class="QVBoxLayout" name="layout">


+ 38
- 23
source/backend/CarlaBackend.hpp View File

@@ -226,85 +226,92 @@ enum OptionsType {
*/
OPTION_PROCESS_MODE = 1,

/*!
* Set the engine transport mode.\n
* Default is TRANSPORT_MODE_INTERNAL.
* \see TransportMode
*/
OPTION_TRANSPORT_MODE = 2,

/*!
* Force mono plugins as stereo, by running 2 instances at the same time.
* \note Not supported by all plugins.
*/
OPTION_FORCE_STEREO = 2,
OPTION_FORCE_STEREO = 3,

/*!
* Use plugin bridges whenever possible.\n
* Default is no, and not recommended at this point!.
* EXPERIMENTAL AND INCOMPLETE!
*/
OPTION_PREFER_PLUGIN_BRIDGES = 3,
OPTION_PREFER_PLUGIN_BRIDGES = 4,

/*!
* Use OSC-UI bridges whenever possible, otherwise UIs will be handled in the main thread.\n
* Default is yes.
*/
OPTION_PREFER_UI_BRIDGES = 4,
OPTION_PREFER_UI_BRIDGES = 5,

#ifdef WANT_DSSI
/*!
* Use (unofficial) dssi-vst chunks feature.\n
* Default is no.
*/
OPTION_USE_DSSI_VST_CHUNKS = 5,
OPTION_USE_DSSI_VST_CHUNKS = 6,
#endif

/*!
* Maximum number of parameters allowed.\n
* Default is MAX_DEFAULT_PARAMETERS.
*/
OPTION_MAX_PARAMETERS = 6,
OPTION_MAX_PARAMETERS = 7,

/*!
* Timeout value in ms for how much to wait for OSC-Bridges to respond.\n
* Default is 4000 (4 secs).
*/
OPTION_OSC_UI_TIMEOUT = 7,
OPTION_OSC_UI_TIMEOUT = 8,

/*!
* Prefered buffer size.
*/
OPTION_PREFERRED_BUFFER_SIZE = 8,
OPTION_PREFERRED_BUFFER_SIZE = 9,

/*!
* Prefered sample rate.
*/
OPTION_PREFERRED_SAMPLE_RATE = 9,
OPTION_PREFERRED_SAMPLE_RATE = 10,

#ifndef BUILD_BRIDGE
/*!
* Set path to the native plugin bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_NATIVE = 10,
OPTION_PATH_BRIDGE_NATIVE = 11,

/*!
* Set path to the POSIX 32bit plugin bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_POSIX32 = 11,
OPTION_PATH_BRIDGE_POSIX32 = 12,

/*!
* Set path to the POSIX 64bit plugin bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_POSIX64 = 12,
OPTION_PATH_BRIDGE_POSIX64 = 13,

/*!
* Set path to the Windows 32bit plugin bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_WIN32 = 13,
OPTION_PATH_BRIDGE_WIN32 = 14,

/*!
* Set path to the Windows 64bit plugin bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_WIN64 = 14,
OPTION_PATH_BRIDGE_WIN64 = 15,
#endif

#ifdef WANT_LV2
@@ -312,43 +319,43 @@ enum OptionsType {
* Set path to the LV2 Gtk2 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_GTK2 = 15,
OPTION_PATH_BRIDGE_LV2_GTK2 = 16,

/*!
* Set path to the LV2 Gtk3 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_GTK3 = 16,
OPTION_PATH_BRIDGE_LV2_GTK3 = 17,

/*!
* Set path to the LV2 Qt4 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_QT4 = 17,
OPTION_PATH_BRIDGE_LV2_QT4 = 18,

/*!
* Set path to the LV2 Qt5 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_QT5 = 18,
OPTION_PATH_BRIDGE_LV2_QT5 = 19,

/*!
* Set path to the LV2 Cocoa UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_COCOA = 19,
OPTION_PATH_BRIDGE_LV2_COCOA = 20,

/*!
* Set path to the LV2 Windows UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_WINDOWS = 20,
OPTION_PATH_BRIDGE_LV2_WINDOWS = 21,

/*!
* Set path to the LV2 X11 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_LV2_X11 = 21,
OPTION_PATH_BRIDGE_LV2_X11 = 22,
#endif

#ifdef WANT_VST
@@ -356,19 +363,19 @@ enum OptionsType {
* Set path to the VST Cocoa UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_VST_COCOA = 22,
OPTION_PATH_BRIDGE_VST_COCOA = 23,

/*!
* Set path to the VST HWND UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_VST_HWND = 23,
OPTION_PATH_BRIDGE_VST_HWND = 24,

/*!
* Set path to the VST X11 UI bridge executable.\n
* Default unset.
*/
OPTION_PATH_BRIDGE_VST_X11 = 24
OPTION_PATH_BRIDGE_VST_X11 = 25
#endif
};

@@ -538,6 +545,14 @@ enum ProcessMode {
PROCESS_MODE_BRIDGE = 4 //!< Special mode, used in plugin-bridges only. RT buffers come from shared memory in a separate host app.
};

/*!
* All the available transport modes
*/
enum TransportMode {
TRANSPORT_MODE_INTERNAL = 0, //!< Internal transport mode.
TRANSPORT_MODE_JACK = 1, //!< JACK transport, only available if driver name is "JACK"
};

/*!
* Callback function the engine will call when something interesting happens.
*


+ 21
- 1
source/backend/CarlaEngine.hpp View File

@@ -257,7 +257,8 @@ struct EngineDevices {
* Engine options.
*/
struct EngineOptions {
ProcessMode processMode;
ProcessMode processMode;
TransportMode transportMode;

bool forceStereo;
bool preferPluginBridges;
@@ -295,6 +296,7 @@ struct EngineOptions {

EngineOptions()
: processMode(PROCESS_MODE_CONTINUOUS_RACK),
transportMode(TRANSPORT_MODE_INTERNAL),
forceStereo(false),
preferPluginBridges(false),
preferUiBridges(true),
@@ -852,6 +854,24 @@ public:
*/
void setCallback(const CallbackFunc func, void* const ptr);

// -------------------------------------------------------------------
// Transport

/*!
* TODO.
*/
virtual void transportPlay();

/*!
* TODO.
*/
virtual void transportPause();

/*!
* TODO.
*/
virtual void transportRelocate(const uint32_t frame);

// -------------------------------------------------------------------
// Error handling



+ 1
- 1
source/backend/CarlaPlugin.hpp View File

@@ -661,7 +661,7 @@ public:
/*!
* Plugin process callback.
*/
virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset = 0);
virtual void process(float** const inBuffer, float** const outBuffer, const uint32_t frames);

/*!
* Tell the plugin the current buffer size has changed.


+ 4
- 0
source/backend/CarlaStandalone.hpp View File

@@ -170,6 +170,10 @@ CARLA_EXPORT void carla_set_engine_option(CarlaOptionsType option, int value, co
CARLA_EXPORT bool carla_load_project(const char* filename);
CARLA_EXPORT bool carla_save_project(const char* filename);

CARLA_EXPORT void carla_transport_play();
CARLA_EXPORT void carla_transport_pause();
CARLA_EXPORT void carla_transport_relocate(uint32_t frames);

CARLA_EXPORT bool carla_add_plugin(CarlaBinaryType btype, CarlaPluginType ptype, const char* filename, const char* name, const char* label, const void* extraPtr);
CARLA_EXPORT bool carla_remove_plugin(unsigned int pluginId);
CARLA_EXPORT void carla_remove_all_plugins();


+ 34
- 0
source/backend/engine/CarlaEngine.cpp View File

@@ -1064,6 +1064,24 @@ void CarlaEngine::setCallback(const CallbackFunc func, void* const ptr)
kData->callbackPtr = ptr;
}

// -----------------------------------------------------------------------
// Transport

void CarlaEngine::transportPlay()
{
kData->time.playing = true;
}

void CarlaEngine::transportPause()
{
kData->time.playing = false;
}

void CarlaEngine::transportRelocate(const uint32_t frame)
{
kData->time.frame = frame;
}

// -----------------------------------------------------------------------
// Error handling

@@ -1141,6 +1159,13 @@ void CarlaEngine::setOption(const OptionsType option, const int value, const cha
fOptions.processMode = static_cast<ProcessMode>(value);
break;

case OPTION_TRANSPORT_MODE:
if (value < CarlaBackend::TRANSPORT_MODE_INTERNAL || value > CarlaBackend::TRANSPORT_MODE_JACK)
return carla_stderr2("carla_set_engine_option(OPTION_TRANSPORT_MODE, %i, \"%s\") - invalid value", value, valueStr);

fOptions.transportMode = static_cast<CarlaBackend::TransportMode>(value);
break;

case OPTION_MAX_PARAMETERS:
CARLA_ENGINE_SET_OPTION_RUNNING_CHECK

@@ -1324,6 +1349,15 @@ void CarlaEngine::proccessPendingEvents()
break;
}

if (kData->time.playing)
kData->time.frame += fBufferSize;

if (fOptions.transportMode == CarlaBackend::TRANSPORT_MODE_INTERNAL)
{
fTimeInfo.playing = kData->time.playing;
fTimeInfo.frame = kData->time.frame;
}

for (unsigned int i=0; i < kData->curPluginCount; i++)
{
// TODO - peak values?


+ 9
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -176,6 +176,15 @@ struct CarlaEngineProtectedData {
out(nullptr) {}
} rack;

struct Time {
bool playing;
uint32_t frame;

Time()
: playing(false),
frame(0) {}
} time;

EnginePluginData* plugins;

CarlaEngineProtectedData(CarlaEngine* const engine)


+ 31
- 1
source/backend/engine/CarlaEngineJack.cpp View File

@@ -15,7 +15,7 @@
* For a full copy of the GNU General Public License see the GPL.txt file
*/

#ifdef WANT_JACK
#if 1//def WANT_JACK

#include "CarlaEngineInternal.hpp"
#include "CarlaBackendUtils.hpp"
@@ -694,6 +694,33 @@ public:
return new CarlaEngineJackClient(kEngineTypeJack, fOptions.processMode, client);
}

// -------------------------------------------------------------------
// Transport

void transportPlay()
{
if (fOptions.transportMode == TRANSPORT_MODE_INTERNAL)
CarlaEngine::transportPlay();
else if (fClient != nullptr)
jackbridge_transport_start(fClient);
}

void transportPause()
{
if (fOptions.transportMode == TRANSPORT_MODE_INTERNAL)
CarlaEngine::transportPause();
else if (fClient != nullptr)
jackbridge_transport_stop(fClient);
}

void transportRelocate(const uint32_t frame)
{
if (fOptions.transportMode == TRANSPORT_MODE_INTERNAL)
CarlaEngine::transportRelocate(frame);
else if (fClient != nullptr)
jackbridge_transport_locate(fClient, frame);
}

// -------------------------------------

protected:
@@ -724,6 +751,9 @@ protected:

void saveTransportInfo()
{
if (fOptions.transportMode != TRANSPORT_MODE_JACK)
return;

fTransportPos.unique_1 = fTransportPos.unique_2 + 1; // invalidate

fTransportState = jackbridge_transport_query(fClient, &fTransportPos);


+ 0
- 4
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -427,10 +427,6 @@ protected:
//fMidiOut.sendMessage();
}

// TESTING
fTimeInfo.playing = true;
fTimeInfo.frame += nframes;

proccessPendingEvents();

return;


+ 1
- 1
source/backend/engine/Makefile View File

@@ -70,7 +70,7 @@ debug:

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

%.cpp.o: %.cpp ../CarlaEngine.hpp CarlaEngineInternal.hpp CarlaEngineOsc.hpp CarlaEngineThread.hpp
%.cpp.o: %.cpp ../CarlaPlugin.hpp ../CarlaEngine.hpp CarlaEngineInternal.hpp CarlaEngineOsc.hpp CarlaEngineThread.hpp
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

$(SHARED): $(OBJS) $(LIBS)


+ 1
- 1
source/backend/plugin/CarlaPlugin.cpp View File

@@ -908,7 +908,7 @@ void CarlaPlugin::prepareForSave()
// -------------------------------------------------------------------
// Plugin processing

void CarlaPlugin::process(float** const, float** const, const uint32_t, const uint32_t)
void CarlaPlugin::process(float** const, float** const, const uint32_t)
{
}



+ 3
- 3
source/backend/plugin/DssiPlugin.cpp View File

@@ -871,7 +871,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;

@@ -987,7 +987,7 @@ public:
{
const EngineEvent& event = kData->event.portIn->getEvent(i);

time = event.time - framesOffset;
time = event.time;

if (time >= frames)
continue;
@@ -1424,7 +1424,7 @@ public:
if (kData->param.data[k].midiCC > 0)
{
value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(framesOffset, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}
}



+ 3
- 3
source/backend/plugin/FluidSynthPlugin.cpp View File

@@ -871,7 +871,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;

@@ -948,7 +948,7 @@ public:
{
const EngineEvent& event = kData->event.portIn->getEvent(i);

time = event.time - framesOffset;
time = event.time;

if (time >= frames)
continue;
@@ -1264,7 +1264,7 @@ public:
if (kData->param.data[k].midiCC > 0)
{
double value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(framesOffset, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}

} // End of Control Output


+ 3
- 3
source/backend/plugin/LadspaPlugin.cpp View File

@@ -748,7 +748,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;

@@ -813,7 +813,7 @@ public:
{
const EngineEvent& event = kData->event.portIn->getEvent(i);

time = event.time - framesOffset;
time = event.time;

if (time >= frames)
continue;
@@ -1095,7 +1095,7 @@ public:
if (kData->param.data[k].midiCC > 0)
{
value = kData->param.ranges[k].normalizeValue(fParamBuffers[k]);
kData->event.portOut->writeControlEvent(framesOffset, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}
}



+ 3
- 3
source/backend/plugin/LinuxSamplerPlugin.cpp View File

@@ -433,7 +433,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;
uint32_t midiEventCount = 0;
@@ -463,7 +463,7 @@ public:
if (! cinEvent)
continue;

time = cinEvent->time - framesOffset;
time = cinEvent->time;

if (time >= frames)
continue;
@@ -658,7 +658,7 @@ public:
if (! minEvent)
continue;

time = minEvent->time - framesOffset;
time = minEvent->time;

if (time >= frames)
continue;


+ 6
- 6
source/backend/plugin/Lv2Plugin.cpp View File

@@ -1916,7 +1916,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;
uint32_t midiEventCount = 0;
@@ -2024,7 +2024,7 @@ public:
if (! cinEvent)
continue;

time = cinEvent->time - framesOffset;
time = cinEvent->time;

if (time >= frames)
continue;
@@ -2260,7 +2260,7 @@ public:
if (! minEvent)
continue;

time = minEvent->time - framesOffset;
time = minEvent->time;

if (time >= frames)
continue;
@@ -2359,7 +2359,7 @@ public:
}

LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]);
aev->time.frames = framesOffset;
aev->time.frames = 0;
aev->body.type = lv2Pos->type;
aev->body.size = lv2Pos->size;
memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(lv2Pos), lv2Pos->size);
@@ -2390,7 +2390,7 @@ public:
}

LV2_Atom_Event* const aev = getLv2AtomEvent(evIn.data[i].atom, evInAtomOffsets[i]);
aev->time.frames = framesOffset;
aev->time.frames = 0;
aev->body.type = atom->type;
aev->body.size = atom->size;
memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size);
@@ -2698,7 +2698,7 @@ public:
if (param.data[k].midiCC > 0)
{
value = (paramBuffers[k] - param.ranges[k].min) / (param.ranges[k].max - param.ranges[k].min);
param.portCout->writeEvent(CarlaEngineParameterChangeEvent, framesOffset, param.data[k].midiChannel, param.data[k].midiCC, value);
param.portCout->writeEvent(CarlaEngineParameterChangeEvent, 0, param.data[k].midiChannel, param.data[k].midiCC, value);
}
}
}


+ 1
- 1
source/backend/plugin/Makefile View File

@@ -55,7 +55,7 @@ debug:

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

%.cpp.o: %.cpp ../CarlaPlugin.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp
%.cpp.o: %.cpp ../CarlaEngine.hpp ../CarlaPlugin.hpp CarlaPluginInternal.hpp CarlaPluginThread.hpp
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

$(SHARED): $(OBJS) $(LIBS)


+ 3
- 3
source/backend/plugin/NativePlugin.cpp View File

@@ -954,7 +954,7 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;

@@ -1091,7 +1091,7 @@ public:
{
const EngineEvent& event = kData->event.portIn->getEvent(i);

time = event.time - framesOffset;
time = event.time;

if (time >= frames)
continue;
@@ -1451,7 +1451,7 @@ public:
if (kData->param.data[k].midiCC > 0)
{
value = kData->param.ranges[k].normalizeValue(curValue);
kData->event.portOut->writeControlEvent(framesOffset, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
kData->event.portOut->writeControlEvent(0, kData->param.data[k].midiChannel, kEngineControlEventTypeParameter, kData->param.data[k].midiCC, value);
}
}



+ 4
- 4
source/backend/plugin/VstPlugin.cpp View File

@@ -893,12 +893,12 @@ public:
// -------------------------------------------------------------------
// Plugin processing

void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const uint32_t framesOffset)
void process(float** const inBuffer, float** const outBuffer, const uint32_t frames)
{
uint32_t i, k;
uint32_t midiEventCount = 0;

vstTimeOffset = framesOffset;
vstTimeOffset = 0;

double aInsPeak[2] = { 0.0 };
double aOutsPeak[2] = { 0.0 };
@@ -954,7 +954,7 @@ public:
if (! cinEvent)
continue;

time = cinEvent->time - framesOffset;
time = cinEvent->time;

if (time >= frames)
continue;
@@ -1147,7 +1147,7 @@ public:
if (! minEvent)
continue;

time = minEvent->time - framesOffset;
time = minEvent->time;

if (time >= frames)
continue;


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

@@ -223,12 +223,13 @@ 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, 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);
standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_MODE, static_cast<int>(standalone.options.processMode), nullptr);
standalone.engine->setOption(CarlaBackend::OPTION_TRANSPORT_MODE, static_cast<int>(standalone.options.transportMode), 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);
@@ -353,6 +354,13 @@ void carla_set_engine_option(CarlaBackend::OptionsType option, int value, const
standalone.options.processMode = static_cast<CarlaBackend::ProcessMode>(value);
break;

case CarlaBackend::OPTION_TRANSPORT_MODE:
if (value < CarlaBackend::TRANSPORT_MODE_INTERNAL || value > CarlaBackend::TRANSPORT_MODE_JACK)
return carla_stderr2("carla_set_engine_option(OPTION_TRANSPORT_MODE, %i, \"%s\") - invalid value", value, valueStr);

standalone.options.transportMode = static_cast<CarlaBackend::TransportMode>(value);
break;

case CarlaBackend::OPTION_FORCE_STEREO:
standalone.options.forceStereo = (value != 0);
break;
@@ -471,6 +479,35 @@ bool carla_save_project(const char* filename)

// -------------------------------------------------------------------------------------------------------------------

void carla_transport_play()
{
carla_debug("carla_transport_play()");
CARLA_ASSERT(standalone.engine != nullptr);

if (standalone.engine != nullptr)
return standalone.engine->transportPlay();
}

void carla_transport_pause()
{
carla_debug("carla_transport_pause()");
CARLA_ASSERT(standalone.engine != nullptr);

if (standalone.engine != nullptr)
return standalone.engine->transportPause();
}

void carla_transport_relocate(uint32_t frames)
{
carla_debug("carla_transport_relocate(%i)", frames);
CARLA_ASSERT(standalone.engine != nullptr);

if (standalone.engine != nullptr)
return standalone.engine->transportRelocate(frames);
}

// -------------------------------------------------------------------------------------------------------------------

bool carla_add_plugin(CarlaBackend::BinaryType btype, CarlaBackend::PluginType ptype, const char* filename, const char* const name, const char* label, const void* extraStuff)
{
carla_debug("carla_add_plugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", CarlaBackend::BinaryType2Str(btype), CarlaBackend::PluginType2Str(ptype), filename, name, label, extraStuff);


+ 1
- 1
source/backend/standalone/Makefile View File

@@ -75,7 +75,7 @@ debug:

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

%.cpp.o: %.cpp
%.cpp.o: %.cpp ../CarlaEngine.hpp ../CarlaPlugin.hpp
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

$(SHARED): $(OBJS) $(LIBS)


+ 47
- 0
source/carla.py View File

@@ -568,6 +568,10 @@ class CarlaMainW(QMainWindow):
self.connect(self.ui.act_help_about, SIGNAL("triggered()"), SLOT("slot_aboutCarla()"))
self.connect(self.ui.act_help_about_qt, SIGNAL("triggered()"), app, SLOT("aboutQt()"))

self.connect(self.ui.ch_transport, SIGNAL("currentIndexChanged(int)"), SLOT("slot_transportModeChanged(int)"))
self.connect(self.ui.b_transport_play, SIGNAL("clicked(bool)"), SLOT("slot_transportPlayPause(bool)"))
self.connect(self.ui.b_transport_stop, SIGNAL("clicked()"), SLOT("slot_transportStop()"))

self.connect(self, SIGNAL("SIGUSR1()"), SLOT("slot_handleSIGUSR1()"))
self.connect(self, SIGNAL("SIGTERM()"), SLOT("slot_handleSIGTERM()"))

@@ -611,6 +615,7 @@ class CarlaMainW(QMainWindow):
Carla.processMode = settings.value("Engine/ProcessMode", PROCESS_MODE_MULTIPLE_CLIENTS, type=int)
Carla.maxParameters = settings.value("Engine/MaxParameters", MAX_DEFAULT_PARAMETERS, type=int)

transportMode = settings.value("Engine/TransportMode", TRANSPORT_MODE_JACK, type=int)
forceStereo = settings.value("Engine/ForceStereo", False, type=bool)
preferPluginBridges = settings.value("Engine/PreferPluginBridges", False, type=bool)
preferUiBridges = settings.value("Engine/PreferUiBridges", True, type=bool)
@@ -667,9 +672,22 @@ class CarlaMainW(QMainWindow):
else:
maxCount = MAX_DEFAULT_PLUGINS

self.ui.ch_transport.blockSignals(True)
self.ui.ch_transport.addItem(self.tr("Internal"))

if audioDriver == "JACK":
self.ui.ch_transport.addItem(self.tr("JACK"))
elif transportMode == TRANSPORT_MODE_JACK:
transportMode = TRANSPORT_MODE_INTERNAL

self.ui.ch_transport.setCurrentIndex(transportMode)
self.ui.ch_transport.blockSignals(False)

for x in range(maxCount):
self.fPluginList.append(None)

Carla.host.set_engine_option(OPTION_TRANSPORT_MODE, transportMode, "")

# Peaks
self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"])
# LEDs and edit dialog parameters
@@ -695,6 +713,12 @@ class CarlaMainW(QMainWindow):
self.killTimer(self.fIdleTimerFast)
self.killTimer(self.fIdleTimerSlow)

settings = QSettings()
settings.setValue("Engine/TransportMode", self.ui.ch_transport.currentIndex())
self.ui.ch_transport.blockSignals(True)
self.ui.ch_transport.clear()
self.ui.ch_transport.blockSignals(False)

def loadProject(self, filename):
self.fProjectFilename = filename
self.setWindowTitle("Carla - %s" % os.path.basename(filename))
@@ -795,6 +819,8 @@ class CarlaMainW(QMainWindow):
self.ui.act_file_open.setEnabled(check)
self.ui.act_engine_start.setEnabled(not check)
self.ui.act_engine_stop.setEnabled(check)
self.ui.act_engine_configure.setEnabled(not check)
self.ui.frame_transport.setEnabled(check)

@pyqtSlot()
def slot_engineStop(self):
@@ -803,6 +829,7 @@ class CarlaMainW(QMainWindow):
self.ui.act_file_open.setEnabled(check)
self.ui.act_engine_start.setEnabled(not check)
self.ui.act_engine_stop.setEnabled(check)
self.ui.frame_transport.setEnabled(check)

@pyqtSlot()
def slot_pluginAdd(self):
@@ -819,6 +846,26 @@ class CarlaMainW(QMainWindow):
def slot_pluginRemoveAll(self):
self.removeAllPlugins()

self.connect(self.ui.ch_transport, SIGNAL("currentIndexChanged(int)"), SLOT("(int)"))
self.connect(self.ui.b_transport_play, SIGNAL("clicked(bool)"), SLOT("(bool)"))
self.connect(self.ui.b_transport_stop, SIGNAL("clicked()"), SLOT("()"))

@pyqtSlot(int)
def slot_transportModeChanged(self, newMode):
Carla.host.set_engine_option(OPTION_TRANSPORT_MODE, newMode, "")

@pyqtSlot(bool)
def slot_transportPlayPause(self, toggled):
if toggled:
Carla.host.transport_play()
else:
Carla.host.transport_pause()

@pyqtSlot()
def slot_transportStop(self):
Carla.host.transport_pause()
Carla.host.transport_relocate(0)

@pyqtSlot()
def slot_aboutCarla(self):
CarlaAboutW(self).exec_()


+ 18
- 0
source/carla_backend.py View File

@@ -191,6 +191,15 @@ class Host(object):
self.lib.carla_save_project.argtypes = [c_char_p]
self.lib.carla_save_project.restype = c_bool

self.lib.carla_transport_play.argtypes = None
self.lib.carla_transport_play.restype = None

self.lib.carla_transport_pause.argtypes = None
self.lib.carla_transport_pause.restype = None

self.lib.carla_transport_relocate.argtypes = [c_uint32]
self.lib.carla_transport_relocate.restype = None

self.lib.carla_add_plugin.argtypes = [c_enum, c_enum, c_char_p, c_char_p, c_char_p, c_void_p]
self.lib.carla_add_plugin.restype = c_bool

@@ -395,6 +404,15 @@ class Host(object):
def save_project(self, filename):
return self.lib.carla_save_project(filename.encode("utf-8"))

def transport_play(self):
self.lib.carla_transport_play()

def transport_pause(self):
self.lib.carla_transport_pause()

def transport_relocate(self, frames):
self.lib.carla_transport_relocate(frames)

def add_plugin(self, btype, ptype, filename, name, label, extraStuff):
cname = name.encode("utf-8") if name else c_nullptr
return self.lib.carla_add_plugin(btype, ptype, filename.encode("utf-8"), cname, label.encode("utf-8"), cast(extraStuff, c_void_p))


+ 29
- 24
source/carla_shared.py View File

@@ -249,29 +249,30 @@ PARAMETER_MAX = -9
# Options Type
OPTION_PROCESS_NAME = 0
OPTION_PROCESS_MODE = 1
OPTION_FORCE_STEREO = 2
OPTION_PREFER_PLUGIN_BRIDGES = 3
OPTION_PREFER_UI_BRIDGES = 4
OPTION_USE_DSSI_VST_CHUNKS = 5
OPTION_MAX_PARAMETERS = 6
OPTION_OSC_UI_TIMEOUT = 7
OPTION_PREFERRED_BUFFER_SIZE = 8
OPTION_PREFERRED_SAMPLE_RATE = 9
OPTION_PATH_BRIDGE_NATIVE = 10
OPTION_PATH_BRIDGE_POSIX32 = 11
OPTION_PATH_BRIDGE_POSIX64 = 12
OPTION_PATH_BRIDGE_WIN32 = 13
OPTION_PATH_BRIDGE_WIN64 = 14
OPTION_PATH_BRIDGE_LV2_GTK2 = 15
OPTION_PATH_BRIDGE_LV2_GTK3 = 16
OPTION_PATH_BRIDGE_LV2_QT4 = 17
OPTION_PATH_BRIDGE_LV2_QT5 = 18
OPTION_PATH_BRIDGE_LV2_COCOA = 19
OPTION_PATH_BRIDGE_LV2_WINDOWS = 20
OPTION_PATH_BRIDGE_LV2_X11 = 21
OPTION_PATH_BRIDGE_VST_COCOA = 22
OPTION_PATH_BRIDGE_VST_HWND = 23
OPTION_PATH_BRIDGE_VST_X11 = 24
OPTION_TRANSPORT_MODE = 2
OPTION_FORCE_STEREO = 3
OPTION_PREFER_PLUGIN_BRIDGES = 4
OPTION_PREFER_UI_BRIDGES = 5
OPTION_USE_DSSI_VST_CHUNKS = 6
OPTION_MAX_PARAMETERS = 7
OPTION_OSC_UI_TIMEOUT = 8
OPTION_PREFERRED_BUFFER_SIZE = 9
OPTION_PREFERRED_SAMPLE_RATE = 10
OPTION_PATH_BRIDGE_NATIVE = 11
OPTION_PATH_BRIDGE_POSIX32 = 12
OPTION_PATH_BRIDGE_POSIX64 = 13
OPTION_PATH_BRIDGE_WIN32 = 14
OPTION_PATH_BRIDGE_WIN64 = 15
OPTION_PATH_BRIDGE_LV2_GTK2 = 16
OPTION_PATH_BRIDGE_LV2_GTK3 = 17
OPTION_PATH_BRIDGE_LV2_QT4 = 18
OPTION_PATH_BRIDGE_LV2_QT5 = 19
OPTION_PATH_BRIDGE_LV2_COCOA = 20
OPTION_PATH_BRIDGE_LV2_WINDOWS = 21
OPTION_PATH_BRIDGE_LV2_X11 = 22
OPTION_PATH_BRIDGE_VST_COCOA = 23
OPTION_PATH_BRIDGE_VST_HWND = 24
OPTION_PATH_BRIDGE_VST_X11 = 25

# Callback Type
CALLBACK_DEBUG = 0
@@ -298,12 +299,16 @@ CALLBACK_NSM_SAVE = 20
CALLBACK_ERROR = 21
CALLBACK_QUIT = 22

# Process Mode Type
# Process Mode
PROCESS_MODE_SINGLE_CLIENT = 0
PROCESS_MODE_MULTIPLE_CLIENTS = 1
PROCESS_MODE_CONTINUOUS_RACK = 2
PROCESS_MODE_PATCHBAY = 3

# Transport Mode
TRANSPORT_MODE_INTERNAL = 0
TRANSPORT_MODE_JACK = 1

# Set BINARY_NATIVE
if HAIKU or LINUX or MACOS:
BINARY_NATIVE = BINARY_POSIX64 if kIs64bit else BINARY_POSIX32


+ 23
- 0
source/libs/jackbridge/jackbridge.c View File

@@ -248,6 +248,15 @@ int jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const ja

// -----------------------------------------------------------------------------

int jackbridge_transport_locate(jack_client_t* client, jack_nframes_t frame)
{
#ifndef JACKBRIDGE_DUMMY
return jack_transport_locate(client, frame);
#else
return 0;
#endif
}

jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos)
{
#ifndef JACKBRIDGE_DUMMY
@@ -256,3 +265,17 @@ jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, j
return JackTransportStopped;
#endif
}

void jackbridge_transport_start(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
jack_transport_start(client);
#endif
}

void jackbridge_transport_stop(jack_client_t* client)
{
#ifndef JACKBRIDGE_DUMMY
jack_transport_stop(client);
#endif
}

+ 6
- 0
source/libs/jackbridge/jackbridge.h View File

@@ -67,7 +67,10 @@ BRIDGE_EXPORT void jackbridge_midi_clear_buffer(void* port_buffer);
BRIDGE_EXPORT jack_midi_data_t* jackbridge_midi_event_reserve(void* port_buffer, jack_nframes_t time, size_t data_size);
BRIDGE_EXPORT int jackbridge_midi_event_write(void* port_buffer, jack_nframes_t time, const jack_midi_data_t* data, size_t data_size);

BRIDGE_EXPORT int jackbridge_transport_locate(jack_client_t* client, jack_nframes_t frame);
BRIDGE_EXPORT jack_transport_state_t jackbridge_transport_query(const jack_client_t* client, jack_position_t* pos);
BRIDGE_EXPORT void jackbridge_transport_start(jack_client_t* client);
BRIDGE_EXPORT void jackbridge_transport_stop(jack_client_t* client);

#ifdef __cplusplus
}
@@ -103,7 +106,10 @@ BRIDGE_EXPORT jack_transport_state_t jackbridge_transport_query(const jack_clien
#define jackbridge_midi_event_reserve jack_midi_event_reserve
#define jackbridge_midi_event_write jack_midi_event_write

#define jackbridge_transport_locate jack_transport_locate
#define jackbridge_transport_query jack_transport_query
#define jackbridge_transport_start jack_transport_start
#define jackbridge_transport_stop jack_transport_stop

#endif // JACKBRIDGE_EXPORT



+ 2
- 0
source/utils/CarlaBackendUtils.hpp View File

@@ -204,6 +204,8 @@ const char* OptionsType2Str(const OptionsType& type)
return "OPTION_PROCESS_NAME";
case OPTION_PROCESS_MODE:
return "OPTION_PROCESS_MODE";
case OPTION_TRANSPORT_MODE:
return "OPTION_TRANSPORT_MODE";
case OPTION_FORCE_STEREO:
return "OPTION_FORCE_STEREO";
case OPTION_PREFER_PLUGIN_BRIDGES:


Loading…
Cancel
Save