@@ -264,7 +264,7 @@ enum OptionsType { | |||
/*! | |||
* JACK auto-connect to hardware ports. | |||
*/ | |||
OPTION_JACK_AUTOCONENCT = 9, | |||
OPTION_JACK_AUTOCONNECT = 9, | |||
/*! | |||
* JACK Transport master. | |||
@@ -1564,7 +1564,7 @@ void CarlaEngine::setOption(const OptionsType option, const int value, const cha | |||
fOptions.oscUiTimeout = static_cast<uint>(value); | |||
break; | |||
case OPTION_JACK_AUTOCONENCT: | |||
case OPTION_JACK_AUTOCONNECT: | |||
CARLA_ENGINE_SET_OPTION_RUNNING_CHECK | |||
fOptions.jackAutoConnect = (value != 0); | |||
break; | |||
@@ -95,8 +95,8 @@ INCLUDEPATH = . .. plugin \ | |||
../../utils | |||
# RtAudio/RtMidi | |||
INCLUDEPATH += rtaudio-4.0.11 rtmidi-2.0.1 | |||
SOURCES += rtaudio-4.0.11/RtAudio.cpp | |||
INCLUDEPATH += rtaudio-4.0.12 rtmidi-2.0.1 | |||
SOURCES += rtaudio-4.0.12/RtAudio.cpp | |||
SOURCES += rtmidi-2.0.1/RtMidi.cpp | |||
# Plugin | |||
@@ -33,6 +33,21 @@ CARLA_BACKEND_START_NAMESPACE | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
static const char** gRetNames = nullptr; | |||
static std::vector<RtAudio::Api> gRtAudioApis; | |||
static void initRtApis() | |||
{ | |||
static bool initiated = false; | |||
if (! initiated) | |||
{ | |||
initiated = true; | |||
RtAudio::getCompiledApi(gRtAudioApis); | |||
} | |||
} | |||
RtMidi::Api getMatchedAudioMidiAPi(const RtAudio::Api rtApi) | |||
{ | |||
switch (rtApi) | |||
@@ -106,6 +121,12 @@ public: | |||
fUsedPortNames.clear(); | |||
fUsedConnections.clear(); | |||
if (gRetNames != nullptr) | |||
{ | |||
delete[] gRetNames; | |||
gRetNames = nullptr; | |||
} | |||
} | |||
// ------------------------------------- | |||
@@ -933,20 +954,6 @@ private: | |||
// ----------------------------------------- | |||
static std::vector<RtAudio::Api> sRtAudioApis; | |||
static void initRtApis() | |||
{ | |||
static bool initiated = false; | |||
if (! initiated) | |||
{ | |||
initiated = true; | |||
RtAudio::getCompiledApi(sRtAudioApis); | |||
} | |||
} | |||
CarlaEngine* CarlaEngine::newRtAudio(RtAudioApi api) | |||
{ | |||
RtAudio::Api rtApi(RtAudio::UNSPECIFIED); | |||
@@ -986,16 +993,16 @@ size_t CarlaEngine::getRtAudioApiCount() | |||
{ | |||
initRtApis(); | |||
return sRtAudioApis.size(); | |||
return gRtAudioApis.size(); | |||
} | |||
const char* CarlaEngine::getRtAudioApiName(const unsigned int index) | |||
{ | |||
initRtApis(); | |||
if (index < sRtAudioApis.size()) | |||
if (index < gRtAudioApis.size()) | |||
{ | |||
const RtAudio::Api& api(sRtAudioApis[index]); | |||
const RtAudio::Api& api(gRtAudioApis[index]); | |||
switch (api) | |||
{ | |||
@@ -1035,11 +1042,47 @@ const char** CarlaEngine::getRtAudioApiDeviceNames(const unsigned int index) | |||
{ | |||
initRtApis(); | |||
if (index < sRtAudioApis.size()) | |||
if (index < gRtAudioApis.size()) | |||
{ | |||
const RtAudio::Api& api(sRtAudioApis[index]); | |||
const RtAudio::Api& api(gRtAudioApis[index]); | |||
RtAudio rtAudio(api); | |||
if (gRetNames != nullptr) | |||
{ | |||
int i=0; | |||
while (gRetNames[i] != nullptr) | |||
delete[] gRetNames[i++]; | |||
delete[] gRetNames; | |||
gRetNames = nullptr; | |||
} | |||
const unsigned int devCount(rtAudio.getDeviceCount()); | |||
if (devCount > 0) | |||
{ | |||
NonRtList<const char*> devNames; | |||
for (unsigned int i=0; i < devCount; ++i) | |||
{ | |||
RtAudio::DeviceInfo devInfo(rtAudio.getDeviceInfo(i)); | |||
if (devInfo.probed && devInfo.outputChannels > 0 /*&& (devInfo.nativeFormats & RTAUDIO_FLOAT32) != 0*/) | |||
devNames.append(carla_strdup(devInfo.name.c_str())); | |||
} | |||
const unsigned int realDevCount(devNames.count()); | |||
gRetNames = new const char*[realDevCount+1]; | |||
for (unsigned int i=0; i < realDevCount; ++i) | |||
gRetNames[i] = devNames.getAt(i); | |||
gRetNames[realDevCount] = nullptr; | |||
devNames.clear(); | |||
return gRetNames; | |||
} | |||
} | |||
return nullptr; | |||
@@ -529,7 +529,7 @@ bool carla_engine_init(const char* driverName, const char* clientName) | |||
# endif | |||
standalone.engine->setOption(CarlaBackend::OPTION_MAX_PARAMETERS, static_cast<int>(standalone.options.maxParameters), nullptr); | |||
standalone.engine->setOption(CarlaBackend::OPTION_OSC_UI_TIMEOUT, static_cast<int>(standalone.options.oscUiTimeout), nullptr); | |||
standalone.engine->setOption(CarlaBackend::OPTION_JACK_AUTOCONENCT, standalone.options.jackAutoConnect ? 1 : 0, nullptr); | |||
standalone.engine->setOption(CarlaBackend::OPTION_JACK_AUTOCONNECT, standalone.options.jackAutoConnect ? 1 : 0, nullptr); | |||
standalone.engine->setOption(CarlaBackend::OPTION_JACK_TIMEMASTER, standalone.options.jackTimeMaster ? 1 : 0, nullptr); | |||
# ifdef WANT_RTAUDIO | |||
standalone.engine->setOption(CarlaBackend::OPTION_RTAUDIO_BUFFER_SIZE, static_cast<int>(standalone.options.rtaudioBufferSize), nullptr); | |||
@@ -701,7 +701,7 @@ void carla_set_engine_option(CarlaOptionsType option, int value, const char* val | |||
standalone.options.oscUiTimeout = static_cast<unsigned int>(value); | |||
break; | |||
case CarlaBackend::OPTION_JACK_AUTOCONENCT: | |||
case CarlaBackend::OPTION_JACK_AUTOCONNECT: | |||
standalone.options.jackAutoConnect = (value != 0); | |||
break; | |||
@@ -972,18 +972,17 @@ class CarlaMainW(QMainWindow): | |||
else: | |||
defaultMode = PROCESS_MODE_CONTINUOUS_RACK | |||
Carla.processMode = settings.value("Engine/ProcessMode", defaultMode, type=int) | |||
Carla.maxParameters = settings.value("Engine/MaxParameters", MAX_DEFAULT_PARAMETERS, type=int) | |||
audioDriver = settings.value("Engine/AudioDriver", CARLA_DEFAULT_AUDIO_DRIVER, type=str) | |||
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) | |||
useDssiVstChunks = settings.value("Engine/UseDssiVstChunks", False, type=bool) | |||
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) | |||
useDssiVstChunks = settings.value("Engine/UseDssiVstChunks", False, type=bool) | |||
oscUiTimeout = settings.value("Engine/OscUiTimeout", 40, type=int) | |||
oscUiTimeout = settings.value("Engine/OscUiTimeout", 40, type=int) | |||
preferredBufferSize = settings.value("Engine/PreferredBufferSize", 512, type=int) | |||
preferredSampleRate = settings.value("Engine/PreferredSampleRate", 44100, type=int) | |||
Carla.processMode = settings.value("Engine/ProcessMode", defaultMode, type=int) | |||
Carla.maxParameters = settings.value("Engine/MaxParameters", MAX_DEFAULT_PARAMETERS, type=int) | |||
if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK: | |||
forceStereo = True | |||
@@ -998,14 +997,26 @@ class CarlaMainW(QMainWindow): | |||
Carla.host.set_engine_option(OPTION_PREFER_UI_BRIDGES, preferUiBridges, "") | |||
Carla.host.set_engine_option(OPTION_USE_DSSI_VST_CHUNKS, useDssiVstChunks, "") | |||
Carla.host.set_engine_option(OPTION_OSC_UI_TIMEOUT, oscUiTimeout, "") | |||
Carla.host.set_engine_option(OPTION_PREFERRED_BUFFER_SIZE, preferredBufferSize, "") | |||
Carla.host.set_engine_option(OPTION_PREFERRED_SAMPLE_RATE, preferredSampleRate, "") | |||
if audioDriver == "JACK": | |||
jackAutoConnect = settings.value("Engine/JackAutoConnect", False, type=bool) | |||
jackTimeMaster = settings.value("Engine/JackTimeMaster", False, type=bool) | |||
Carla.host.set_engine_option(OPTION_JACK_AUTOCONNECT, jackAutoConnect, "") | |||
Carla.host.set_engine_option(OPTION_JACK_TIMEMASTER, jackTimeMaster, "") | |||
else: | |||
rtaudioBufferSize = settings.value("Engine/RtAudioBufferSize", 512, type=int) | |||
rtaudioSampleRate = settings.value("Engine/RtAudioSampleRate", 44100, type=int) | |||
rtaudioDevice = settings.value("Engine/RtAudioDevice", "", type=str) | |||
Carla.host.set_engine_option(OPTION_RTAUDIO_BUFFER_SIZE, rtaudioBufferSize, "") | |||
Carla.host.set_engine_option(OPTION_RTAUDIO_SAMPLE_RATE, rtaudioSampleRate, "") | |||
Carla.host.set_engine_option(OPTION_RTAUDIO_SAMPLE_RATE, 0, rtaudioDevice) | |||
# --------------------------------------------- | |||
# Start | |||
audioDriver = settings.value("Engine/AudioDriver", CARLA_DEFAULT_AUDIO_DRIVER, type=str) | |||
if not Carla.host.engine_init(audioDriver, self.fClientName): | |||
if self.fFirstEngineInit: | |||
self.fFirstEngineInit = False | |||
@@ -57,6 +57,27 @@ else: | |||
MACOS = False | |||
WINDOWS = False | |||
# ------------------------------------------------------------------------------------------------------------ | |||
# Convert a ctypes char** into a python string list | |||
def charStringList(charPtr): | |||
i = 0 | |||
retList = [] | |||
if not charPtr: | |||
return retList | |||
while True: | |||
char_p = charPtr[i] | |||
if not char_p: | |||
break | |||
retList.append(char_p.decode("utf-8", errors="ignore")) | |||
i += 1 | |||
return retList | |||
# ------------------------------------------------------------------------------------------------------------ | |||
# Convert a ctypes struct into a python dict | |||
@@ -175,7 +196,7 @@ OPTION_PREFER_UI_BRIDGES = 5 | |||
OPTION_USE_DSSI_VST_CHUNKS = 6 | |||
OPTION_MAX_PARAMETERS = 7 | |||
OPTION_OSC_UI_TIMEOUT = 8 | |||
OPTION_JACK_AUTOCONENCT = 9 | |||
OPTION_JACK_AUTOCONNECT = 9 | |||
OPTION_JACK_TIMEMASTER = 10 | |||
OPTION_RTAUDIO_BUFFER_SIZE = 11 | |||
OPTION_RTAUDIO_SAMPLE_RATE = 12 | |||
@@ -635,8 +656,7 @@ class Host(object): | |||
return self.lib.carla_get_engine_driver_name(index) | |||
def get_engine_driver_device_names(self, index): | |||
# FIXME | |||
return self.lib.carla_get_engine_driver_device_names(index) | |||
return charStringList(self.lib.carla_get_engine_driver_device_names(index)) | |||
def get_internal_plugin_count(self): | |||
return self.lib.carla_get_internal_plugin_count() | |||
@@ -220,8 +220,8 @@ const char* OptionsType2Str(const OptionsType& type) | |||
return "OPTION_MAX_PARAMETERS"; | |||
case OPTION_OSC_UI_TIMEOUT: | |||
return "OPTION_OSC_UI_TIMEOUT"; | |||
case OPTION_JACK_AUTOCONENCT: | |||
return "OPTION_JACK_AUTOCONENCT"; | |||
case OPTION_JACK_AUTOCONNECT: | |||
return "OPTION_JACK_AUTOCONNECT"; | |||
case OPTION_JACK_TIMEMASTER: | |||
return "OPTION_JACK_TIMEMASTER"; | |||
#ifdef WANT_RTAUDIO | |||