- *
- * 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 COPYING file
- */
-
-#include "carla_backend_standalone.hpp"
-#include "carla_plugin.hpp"
-#include "carla_native.h"
-
-// -------------------------------------------------------------------------------------------------------------------
-
-// Single, standalone engine
-struct CarlaBackendStandalone {
- CarlaBackend::CarlaEngineOptions options;
- CarlaBackend::CarlaEngine* engine;
- CarlaBackend::CallbackFunc callback;
- CarlaString lastError;
- CarlaString procName;
- bool started;
-
- CarlaBackendStandalone()
- : engine(nullptr),
- callback(nullptr),
- started(false) {}
-
-} standalone;
-
-// -------------------------------------------------------------------------------------------------------------------
-
-const char* get_extended_license_text()
-{
- qDebug("CarlaBackendStandalone::get_extended_license_text()");
-
- static CarlaString extendedLicenseText;
-
- if (extendedLicenseText.isEmpty())
- {
- QString text("This current Carla build is using the following features and 3rd-party code:
");
- text += "";
-#ifdef WANT_LADSPA
- text += "LADSPA plugin support, http://www.ladspa.org/ ";
-#endif
-#ifdef WANT_DSSI
- text += "DSSI plugin support, http://dssi.sourceforge.net/ ";
-#endif
-#ifdef WANT_LV2
- text += "LV2 plugin support, http://lv2plug.in/ ";
-#endif
-#ifdef WANT_VST
-# ifdef VESTIGE_HEADER
- text += "VST plugin support, using VeSTige header by Javier Serrano Polo ";
-# else
- text += "VST plugin support, using official VST SDK 2.4 (trademark of Steinberg Media Technologies GmbH) ";
-# endif
-#endif
-#ifdef WANT_ZYNADDSUBFX
- text += "ZynAddSubFX plugin code, http://zynaddsubfx.sf.net/ ";
-#endif
-#ifdef WANT_FLUIDSYNTH
- text += "FluidSynth library for SF2 support, http://www.fluidsynth.org/ ";
-#endif
-#ifdef WANT_LINUXSAMPLER
- text += "LinuxSampler library for GIG and SFZ support*, http://www.linuxsampler.org/ ";
-#endif
- text += "liblo library for OSC support, http://liblo.sourceforge.net/ ";
-#ifdef WANT_LV2
- text += "serd, sord, sratom and lilv libraries for LV2 discovery, http://drobilla.net/software/lilv/ ";
-#endif
-#ifdef CARLA_ENGINE_RTAUDIO
- text += "RtAudio and RtMidi libraries for extra Audio and MIDI support, http://www.music.mcgill.ca/~gary/rtaudio/ ";
-#endif
- text += " ";
-
-#ifdef WANT_LINUXSAMPLER
- text += "(*) Using LinuxSampler code in commercial hardware or software products is not allowed without prior written authorization by the authors.
";
-#endif
-
- extendedLicenseText = text.toUtf8().constData();
- }
-
- return extendedLicenseText;
-}
-
-unsigned int get_engine_driver_count()
-{
- qDebug("CarlaBackendStandalone::get_engine_driver_count()");
-
- return CarlaBackend::CarlaEngine::getDriverCount();
-}
-
-const char* get_engine_driver_name(unsigned int index)
-{
- qDebug("CarlaBackendStandalone::get_engine_driver_name(%i)", index);
-
- return CarlaBackend::CarlaEngine::getDriverName(index);
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-unsigned int get_internal_plugin_count()
-{
- qDebug("CarlaBackendStandalone::get_internal_plugin_count()");
-
- return CarlaBackend::CarlaPlugin::getNativePluginCount();
-}
-
-const PluginInfo* get_internal_plugin_info(unsigned int pluginId)
-{
- qDebug("CarlaBackendStandalone::get_internal_plugin_info(%i)", pluginId);
-
- static PluginInfo info;
-
- const PluginDescriptor* const nativePlugin = CarlaBackend::CarlaPlugin::getNativePluginDescriptor(pluginId);
-
- CARLA_ASSERT(nativePlugin);
-
- // as internal plugin, this must never fail
- if (! nativePlugin)
- return nullptr;
-
- info.type = CarlaBackend::PLUGIN_INTERNAL;
- info.category = static_cast(nativePlugin->category);
- info.hints = 0x0;
- info.name = nativePlugin->name;
- info.label = nativePlugin->label;
- info.maker = nativePlugin->maker;
- info.copyright = nativePlugin->copyright;
-
- if (nativePlugin->hints & PLUGIN_IS_SYNTH)
- info.hints |= CarlaBackend::PLUGIN_IS_SYNTH;
- if (nativePlugin->hints & PLUGIN_HAS_GUI)
- info.hints |= CarlaBackend::PLUGIN_HAS_GUI;
- if (nativePlugin->hints & PLUGIN_USES_SINGLE_THREAD)
- info.hints |= CarlaBackend::PLUGIN_USES_SINGLE_THREAD;
-
- return &info;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-bool engine_init(const char* driverName, const char* clientName)
-{
- qDebug("CarlaBackendStandalone::engine_init(\"%s\", \"%s\")", driverName, clientName);
- CARLA_ASSERT(! standalone.engine);
-
- standalone.engine = CarlaBackend::CarlaEngine::newDriverByName(driverName);
-
- if (! standalone.engine)
- {
- standalone.lastError = "The seleted audio driver is not available!";
- return false;
- }
-
-#ifndef Q_OS_WIN
- // TODO: make this an option, put somewhere else
- if (! getenv("WINE_RT"))
- {
- carla_setenv("WINE_RT", "15");
- carla_setenv("WINE_SVR_RT", "10");
- }
-#endif
-
- standalone.engine->setCallback(standalone.callback, nullptr);
-
- standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_MODE, standalone.options.processMode, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_HIGH_PRECISION, standalone.options.processHighPrecision, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_MAX_PARAMETERS, standalone.options.maxParameters, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PREFERRED_BUFFER_SIZE, standalone.options.preferredBufferSize, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PREFERRED_SAMPLE_RATE, standalone.options.preferredSampleRate, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_FORCE_STEREO, standalone.options.forceStereo, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_USE_DSSI_VST_CHUNKS, standalone.options.useDssiVstChunks, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PREFER_PLUGIN_BRIDGES, standalone.options.preferPluginBridges, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PREFER_UI_BRIDGES, standalone.options.preferUiBridges, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_OSC_UI_TIMEOUT, standalone.options.oscUiTimeout, nullptr);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_POSIX32, 0, standalone.options.bridge_posix32);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_POSIX64, 0, standalone.options.bridge_posix64);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_WIN32, 0, standalone.options.bridge_win32);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_WIN64, 0, standalone.options.bridge_win64);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_GTK2, 0, standalone.options.bridge_lv2gtk2);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_GTK3, 0, standalone.options.bridge_lv2gtk3);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_QT4, 0, standalone.options.bridge_lv2qt4);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_QT5, 0, standalone.options.bridge_lv2qt5);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_COCOA, 0, standalone.options.bridge_lv2cocoa);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_WINDOWS, 0, standalone.options.bridge_lv2win);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_LV2_X11, 0, standalone.options.bridge_lv2qt4);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_VST_COCOA, 0, standalone.options.bridge_vstcocoa);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_VST_HWND, 0, standalone.options.bridge_vsthwnd);
- standalone.engine->setOption(CarlaBackend::OPTION_PATH_BRIDGE_VST_X11, 0, standalone.options.bridge_vstx11);
-
- if (standalone.procName.isNotEmpty())
- standalone.engine->setOption(CarlaBackend::OPTION_PROCESS_NAME, 0, standalone.procName);
-
- standalone.started = standalone.engine->init(clientName);
-
- if (standalone.started)
- {
- standalone.lastError = "no error";
- }
- else if (standalone.engine)
- {
- delete standalone.engine;
- standalone.engine = nullptr;
- }
-
- return standalone.started;
-}
-
-bool engine_close()
-{
- qDebug("CarlaBackendStandalone::engine_close()");
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- {
- standalone.lastError = "Engine is not started";
- return false;
- }
-
- standalone.engine->aboutToClose();
- standalone.engine->removeAllPlugins();
- bool closed = standalone.engine->close();
-
- standalone.started = false;
-
- // cleanup static data
- get_plugin_info(0);
- get_parameter_info(0, 0);
- get_parameter_scalepoint_info(0, 0, 0);
- get_chunk_data(0);
- get_program_name(0, 0);
- get_midi_program_name(0, 0);
- get_real_plugin_name(0);
-
- delete standalone.engine;
- standalone.engine = nullptr;
-
- return closed;
-}
-
-bool is_engine_running()
-{
- qDebug("CarlaBackendStandalone::is_engine_running()");
-
- return standalone.engine && standalone.engine->isRunning();
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-short add_plugin(CarlaBackend::BinaryType btype, CarlaBackend::PluginType ptype, const char* filename, const char* const name, const char* label, void* extraStuff)
-{
- qDebug("CarlaBackendStandalone::add_plugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", CarlaBackend::BinaryType2Str(btype), CarlaBackend::PluginType2Str(ptype), filename, name, label, extraStuff);
- CARLA_ASSERT(standalone.engine);
-
- if (btype != CarlaBackend::BINARY_NATIVE && ! extraStuff)
- {
- switch (btype)
- {
- case CarlaBackend::BINARY_NONE:
- case CarlaBackend::BINARY_OTHER:
- break;
- case CarlaBackend::BINARY_POSIX32:
- extraStuff = (void*)(const char*)standalone.options.bridge_posix32;
- break;
- case CarlaBackend::BINARY_POSIX64:
- extraStuff = (void*)(const char*)standalone.options.bridge_posix64;
- break;
- case CarlaBackend::BINARY_WIN32:
- extraStuff = (void*)(const char*)standalone.options.bridge_win32;
- break;
- case CarlaBackend::BINARY_WIN64:
- extraStuff = (void*)(const char*)standalone.options.bridge_win64;
- break;
- }
- }
-
- if (standalone.engine && standalone.engine->isRunning())
- return standalone.engine->addPlugin(btype, ptype, filename, name, label, extraStuff);
-
- standalone.lastError = "Engine is not started";
- return -1;
-}
-
-bool remove_plugin(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::remove_plugin(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (standalone.engine)
- return standalone.engine->removePlugin(pluginId);
-
- standalone.lastError = "Engine is not started";
- return false;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-const PluginInfo* get_plugin_info(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_plugin_info(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static PluginInfo info;
-
- // reset
- info.type = CarlaBackend::PLUGIN_NONE;
- info.category = CarlaBackend::PLUGIN_CATEGORY_NONE;
- info.hints = 0x0;
- info.binary = nullptr;
- info.name = nullptr;
- info.uniqueId = 0;
-
- // cleanup
- if (info.label)
- {
- free((void*)info.label);
- info.label = nullptr;
- }
-
- if (info.maker)
- {
- free((void*)info.maker);
- info.maker = nullptr;
- }
-
- if (info.copyright)
- {
- free((void*)info.copyright);
- info.copyright = nullptr;
- }
-
- if (! standalone.engine)
- return &info;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- char strBufLabel[STR_MAX] = { 0 };
- char strBufMaker[STR_MAX] = { 0 };
- char strBufCopyright[STR_MAX] = { 0 };
-
- info.type = plugin->type();
- info.category = plugin->category();
- info.hints = plugin->hints();
- info.binary = plugin->filename();
- info.name = plugin->name();
- info.uniqueId = plugin->uniqueId();
-
- plugin->getLabel(strBufLabel);
- info.label = strdup(strBufLabel);
-
- plugin->getMaker(strBufMaker);
- info.maker = strdup(strBufMaker);
-
- plugin->getCopyright(strBufCopyright);
- info.copyright = strdup(strBufCopyright);
-
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_plugin_info(%i) - could not find plugin", pluginId);
- return &info;
-}
-
-const PortCountInfo* get_audio_port_count_info(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_audio_port_count_info(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static PortCountInfo info;
-
- // reset
- info.ins = 0;
- info.outs = 0;
- info.total = 0;
-
- if (! standalone.engine)
- return &info;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- info.ins = plugin->audioInCount();
- info.outs = plugin->audioOutCount();
- info.total = info.ins + info.outs;
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_audio_port_count_info(%i) - could not find plugin", pluginId);
- return &info;
-}
-
-const PortCountInfo* get_midi_port_count_info(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_midi_port_count_info(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static PortCountInfo info;
-
- // reset
- info.ins = 0;
- info.outs = 0;
- info.total = 0;
-
- if (! standalone.engine)
- return &info;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- info.ins = plugin->midiInCount();
- info.outs = plugin->midiOutCount();
- info.total = info.ins + info.outs;
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_midi_port_count_info(%i) - could not find plugin", pluginId);
- return &info;
-}
-
-const PortCountInfo* get_parameter_count_info(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_parameter_count_info(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static PortCountInfo info;
-
- // reset
- info.ins = 0;
- info.outs = 0;
- info.total = 0;
-
- if (! standalone.engine)
- return &info;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- plugin->getParameterCountInfo(&info.ins, &info.outs, &info.total);
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_count_info(%i) - could not find plugin", pluginId);
- return &info;
-}
-
-const ParameterInfo* get_parameter_info(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_parameter_info(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- static ParameterInfo info;
-
- // reset
- info.scalePointCount = 0;
-
- // cleanup
- if (info.name)
- {
- free((void*)info.name);
- info.name = nullptr;
- }
-
- if (info.symbol)
- {
- free((void*)info.symbol);
- info.symbol = nullptr;
- }
-
- if (info.unit)
- {
- free((void*)info.unit);
- info.unit = nullptr;
- }
-
- if (! standalone.engine)
- return &info;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- {
- char strBufName[STR_MAX] = { 0 };
- char strBufSymbol[STR_MAX] = { 0 };
- char strBufUnit[STR_MAX] = { 0 };
-
- info.scalePointCount = plugin->parameterScalePointCount(parameter_id);
-
- plugin->getParameterName(parameter_id, strBufName);
- info.name = strdup(strBufName);
-
- plugin->getParameterSymbol(parameter_id, strBufSymbol);
- info.symbol = strdup(strBufSymbol);
-
- plugin->getParameterUnit(parameter_id, strBufUnit);
- info.unit = strdup(strBufUnit);
- }
- else
- qCritical("CarlaBackendStandalone::get_parameter_info(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
-
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_info(%i, %i) - could not find plugin", pluginId, parameter_id);
- return &info;
-}
-
-const ScalePointInfo* get_parameter_scalepoint_info(unsigned short pluginId, uint32_t parameter_id, uint32_t scalepoint_id)
-{
- qDebug("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i)", pluginId, parameter_id, scalepoint_id);
- CARLA_ASSERT(standalone.engine);
-
- static ScalePointInfo info;
-
- // reset
- info.value = 0.0;
-
- // cleanup
- if (info.label)
- {
- free((void*)info.label);
- info.label = nullptr;
- }
-
- if (! standalone.engine)
- return &info;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- {
- if (scalepoint_id < plugin->parameterScalePointCount(parameter_id))
- {
- char strBufLabel[STR_MAX] = { 0 };
-
- info.value = plugin->getParameterScalePointValue(parameter_id, scalepoint_id);
-
- plugin->getParameterScalePointLabel(parameter_id, scalepoint_id, strBufLabel);
- info.label = strdup(strBufLabel);
- }
- else
- qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - scalepoint_id out of bounds", pluginId, parameter_id, scalepoint_id);
- }
- else
- qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - parameter_id out of bounds", pluginId, parameter_id, parameter_id);
-
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_scalepoint_info(%i, %i, %i) - could not find plugin", pluginId, parameter_id, scalepoint_id);
- return &info;
-}
-
-const GuiInfo* get_gui_info(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_gui_info(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static GuiInfo info;
-
- // reset
- info.type = CarlaBackend::GUI_NONE;
- info.resizable = false;
-
- if (! standalone.engine)
- return &info;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- plugin->getGuiInfo(&info.type, &info.resizable);
- return &info;
- }
-
- qCritical("CarlaBackendStandalone::get_gui_info(%i) - could not find plugin", pluginId);
- return &info;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-const CarlaBackend::ParameterData* get_parameter_data(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_parameter_data(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- static CarlaBackend::ParameterData data;
-
- if (! standalone.engine)
- return &data;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->parameterData(parameter_id);
-
- qCritical("CarlaBackendStandalone::get_parameter_data(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
- return &data;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_data(%i, %i) - could not find plugin", pluginId, parameter_id);
- return &data;
-}
-
-const CarlaBackend::ParameterRanges* get_parameter_ranges(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_parameter_ranges(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- static CarlaBackend::ParameterRanges ranges;
-
- if (! standalone.engine)
- return &ranges;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->parameterRanges(parameter_id);
-
- qCritical("CarlaBackendStandalone::get_parameter_ranges(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
- return &ranges;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_ranges(%i, %i) - could not find plugin", pluginId, parameter_id);
- return &ranges;
-}
-
-const CarlaBackend::MidiProgramData* get_midi_program_data(unsigned short pluginId, uint32_t midi_program_id)
-{
- qDebug("CarlaBackendStandalone::get_midi_program_data(%i, %i)", pluginId, midi_program_id);
- CARLA_ASSERT(standalone.engine);
-
- static CarlaBackend::MidiProgramData data;
-
- if (! standalone.engine)
- return &data;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (midi_program_id < plugin->midiProgramCount())
- return plugin->midiProgramData(midi_program_id);
-
- qCritical("CarlaBackendStandalone::get_midi_program_data(%i, %i) - midi_program_id out of bounds", pluginId, midi_program_id);
- return &data;
- }
-
- qCritical("CarlaBackendStandalone::get_midi_program_data(%i, %i) - could not find plugin", pluginId, midi_program_id);
- return &data;
-}
-
-const CarlaBackend::CustomData* get_custom_data(unsigned short pluginId, uint32_t custom_data_id)
-{
- qDebug("CarlaBackendStandalone::get_custom_data(%i, %i)", pluginId, custom_data_id);
- CARLA_ASSERT(standalone.engine);
-
- static CarlaBackend::CustomData data;
-
- if (! standalone.engine)
- return &data;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (custom_data_id < plugin->customDataCount())
- return plugin->customData(custom_data_id);
-
- qCritical("CarlaBackendStandalone::get_custom_data(%i, %i) - custom_data_id out of bounds", pluginId, custom_data_id);
- return &data;
- }
-
- qCritical("CarlaBackendStandalone::get_custom_data(%i, %i) - could not find plugin", pluginId, custom_data_id);
- return &data;
-}
-
-const char* get_chunk_data(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_chunk_data(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static const char* chunk_data = nullptr;
-
- // cleanup
- if (chunk_data)
- {
- free((void*)chunk_data);
- chunk_data = nullptr;
- }
-
- if (! standalone.engine)
- return nullptr;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (plugin->hints() & CarlaBackend::PLUGIN_USES_CHUNKS)
- {
- void* data = nullptr;
- const int32_t dataSize = plugin->chunkData(&data);
-
- if (data && dataSize >= 4)
- {
- const QByteArray chunk((const char*)data, dataSize);
- chunk_data = strdup(chunk.toBase64().constData());
- }
- else
- qCritical("CarlaBackendStandalone::get_chunk_data(%i) - got invalid chunk data", pluginId);
- }
- else
- qCritical("CarlaBackendStandalone::get_chunk_data(%i) - plugin does not support chunks", pluginId);
-
- return chunk_data;
- }
-
- qCritical("CarlaBackendStandalone::get_chunk_data(%i) - could not find plugin", pluginId);
- return nullptr;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-uint32_t get_parameter_count(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_parameter_count(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->parameterCount();
-
- qCritical("CarlaBackendStandalone::get_parameter_count(%i) - could not find plugin", pluginId);
- return 0;
-}
-
-uint32_t get_program_count(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_program_count(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->programCount();
-
- qCritical("CarlaBackendStandalone::get_program_count(%i) - could not find plugin", pluginId);
- return 0;
-}
-
-uint32_t get_midi_program_count(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_midi_program_count(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->midiProgramCount();
-
- qCritical("CarlaBackendStandalone::get_midi_program_count(%i) - could not find plugin", pluginId);
- return 0;
-}
-
-uint32_t get_custom_data_count(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_custom_data_count(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->customDataCount();
-
- qCritical("CarlaBackendStandalone::get_custom_data_count(%i) - could not find plugin", pluginId);
- return 0;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-const char* get_parameter_text(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_parameter_text(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- static char textBuf[STR_MAX];
- memset(textBuf, 0, sizeof(char)*STR_MAX);
-
- if (! standalone.engine)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- {
- plugin->getParameterText(parameter_id, textBuf);
- return textBuf;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_text(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
- return nullptr;
- }
-
- qCritical("CarlaBackendStandalone::get_parameter_text(%i, %i) - could not find plugin", pluginId, parameter_id);
- return nullptr;
-}
-
-const char* get_program_name(unsigned short pluginId, uint32_t program_id)
-{
- qDebug("CarlaBackendStandalone::get_program_name(%i, %i)", pluginId, program_id);
- CARLA_ASSERT(standalone.engine);
-
- static const char* program_name = nullptr;
-
- // cleanup
- if (program_name)
- {
- free((void*)program_name);
- program_name = nullptr;
- }
-
- if (! standalone.engine)
- return nullptr;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (program_id < plugin->programCount())
- {
- char strBuf[STR_MAX] = { 0 };
-
- plugin->getProgramName(program_id, strBuf);
- program_name = strdup(strBuf);
-
- return program_name;
- }
-
- qCritical("CarlaBackendStandalone::get_program_name(%i, %i) - program_id out of bounds", pluginId, program_id);
- return nullptr;
- }
-
- qCritical("CarlaBackendStandalone::get_program_name(%i, %i) - could not find plugin", pluginId, program_id);
- return nullptr;
-}
-
-const char* get_midi_program_name(unsigned short pluginId, uint32_t midi_program_id)
-{
- qDebug("CarlaBackendStandalone::get_midi_program_name(%i, %i)", pluginId, midi_program_id);
- CARLA_ASSERT(standalone.engine);
-
- static const char* midi_program_name = nullptr;
-
- // cleanup
- if (midi_program_name)
- {
- free((void*)midi_program_name);
- midi_program_name = nullptr;
- }
-
- if (! standalone.engine)
- return nullptr;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (midi_program_id < plugin->midiProgramCount())
- {
- char strBuf[STR_MAX] = { 0 };
-
- plugin->getMidiProgramName(midi_program_id, strBuf);
- midi_program_name = strdup(strBuf);
-
- return midi_program_name;
- }
-
- qCritical("CarlaBackendStandalone::get_midi_program_name(%i, %i) - program_id out of bounds", pluginId, midi_program_id);
- return nullptr;
- }
-
- qCritical("CarlaBackendStandalone::get_midi_program_name(%i, %i) - could not find plugin", pluginId, midi_program_id);
- return nullptr;
-}
-
-const char* get_real_plugin_name(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_real_plugin_name(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- static const char* real_plugin_name = nullptr;
-
- // cleanup
- if (real_plugin_name)
- {
- free((void*)real_plugin_name);
- real_plugin_name = nullptr;
- }
-
- if (! standalone.engine)
- return nullptr;
-
- if (! standalone.started)
- return nullptr;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- char strBuf[STR_MAX] = { 0 };
-
- plugin->getRealName(strBuf);
- real_plugin_name = strdup(strBuf);
-
- return real_plugin_name;
- }
-
- qCritical("CarlaBackendStandalone::get_real_plugin_name(%i) - could not find plugin", pluginId);
- return nullptr;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-int32_t get_current_program_index(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_current_program_index(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return -1;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->currentProgram();
-
- qCritical("CarlaBackendStandalone::get_current_program_index(%i) - could not find plugin", pluginId);
- return -1;
-}
-
-int32_t get_current_midi_program_index(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::get_current_midi_program_index(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return -1;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->currentMidiProgram();
-
- qCritical("CarlaBackendStandalone::get_current_midi_program_index(%i) - could not find plugin", pluginId);
- return -1;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-double get_default_parameter_value(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_default_parameter_value(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0.0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->parameterRanges(parameter_id)->def;
-
- qCritical("CarlaBackendStandalone::get_default_parameter_value(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
- return 0.0;
- }
-
- qCritical("CarlaBackendStandalone::get_default_parameter_value(%i, %i) - could not find plugin", pluginId, parameter_id);
- return 0.0;
-}
-
-double get_current_parameter_value(unsigned short pluginId, uint32_t parameter_id)
-{
- qDebug("CarlaBackendStandalone::get_current_parameter_value(%i, %i)", pluginId, parameter_id);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0.0;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->getParameterValue(parameter_id);
-
- qCritical("CarlaBackendStandalone::get_current_parameter_value(%i, %i) - parameter_id out of bounds", pluginId, parameter_id);
- return 0.0;
- }
-
- qCritical("CarlaBackendStandalone::get_current_parameter_value(%i, %i) - could not find plugin", pluginId, parameter_id);
- return 0.0;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-double get_input_peak_value(unsigned short pluginId, unsigned short port_id)
-{
- CARLA_ASSERT(standalone.engine);
- CARLA_ASSERT(port_id == 1 || port_id == 2);
-
- if (! standalone.engine)
- return 0.0;
-
-#if 0
- if (pluginId >= standalone.engine->maxPluginNumber())
- {
- qCritical("CarlaBackendStandalone::get_input_peak_value(%i, %i) - invalid plugin value", pluginId, port_id);
- return 0.0;
- }
-#endif
-
- if (port_id == 1 || port_id == 2)
- return standalone.engine->getInputPeak(pluginId, port_id-1);
-
- qCritical("CarlaBackendStandalone::get_input_peak_value(%i, %i) - invalid port value", pluginId, port_id);
- return 0.0;
-}
-
-double get_output_peak_value(unsigned short pluginId, unsigned short port_id)
-{
- CARLA_ASSERT(standalone.engine);
- CARLA_ASSERT(port_id == 1 || port_id == 2);
-
- if (! standalone.engine)
- return 0.0;
-
-#if 0
- if (pluginId >= standalone.engine->maxPluginNumber())
- {
- qCritical("CarlaBackendStandalone::get_input_peak_value(%i, %i) - invalid plugin value", pluginId, port_id);
- return 0.0;
- }
-#endif
-
- if (port_id == 1 || port_id == 2)
- return standalone.engine->getOutputPeak(pluginId, port_id-1);
-
- qCritical("CarlaBackendStandalone::get_output_peak_value(%i, %i) - invalid port value", pluginId, port_id);
- return 0.0;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void set_active(unsigned short pluginId, bool onOff)
-{
- qDebug("CarlaBackendStandalone::set_active(%i, %s)", pluginId, bool2str(onOff));
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setActive(onOff, true, false);
-
- qCritical("CarlaBackendStandalone::set_active(%i, %s) - could not find plugin", pluginId, bool2str(onOff));
-}
-
-void set_drywet(unsigned short pluginId, double value)
-{
- qDebug("CarlaBackendStandalone::set_drywet(%i, %g)", pluginId, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setDryWet(value, true, false);
-
- qCritical("CarlaBackendStandalone::set_drywet(%i, %g) - could not find plugin", pluginId, value);
-}
-
-void set_volume(unsigned short pluginId, double value)
-{
- qDebug("CarlaBackendStandalone::set_volume(%i, %g)", pluginId, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setVolume(value, true, false);
-
- qCritical("CarlaBackendStandalone::set_volume(%i, %g) - could not find plugin", pluginId, value);
-}
-
-void set_balance_left(unsigned short pluginId, double value)
-{
- qDebug("CarlaBackendStandalone::set_balance_left(%i, %g)", pluginId, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setBalanceLeft(value, true, false);
-
- qCritical("CarlaBackendStandalone::set_balance_left(%i, %g) - could not find plugin", pluginId, value);
-}
-
-void set_balance_right(unsigned short pluginId, double value)
-{
- qDebug("CarlaBackendStandalone::set_balance_right(%i, %g)", pluginId, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setBalanceRight(value, true, false);
-
- qCritical("CarlaBackendStandalone::set_balance_right(%i, %g) - could not find plugin", pluginId, value);
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void set_parameter_value(unsigned short pluginId, uint32_t parameter_id, double value)
-{
- qDebug("CarlaBackendStandalone::set_parameter_value(%i, %i, %g)", pluginId, parameter_id, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->setParameterValue(parameter_id, value, true, true, false);
-
- qCritical("CarlaBackendStandalone::set_parameter_value(%i, %i, %g) - parameter_id out of bounds", pluginId, parameter_id, value);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_parameter_value(%i, %i, %g) - could not find plugin", pluginId, parameter_id, value);
-}
-
-void set_parameter_midi_channel(unsigned short pluginId, uint32_t parameter_id, uint8_t channel)
-{
- qDebug("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i)", pluginId, parameter_id, channel);
- CARLA_ASSERT(standalone.engine);
- CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
-
- if (channel >= MAX_MIDI_CHANNELS)
- {
- qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - invalid channel number", pluginId, parameter_id, channel);
- return;
- }
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->setParameterMidiChannel(parameter_id, channel, true, false);
-
- qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - parameter_id out of bounds", pluginId, parameter_id, channel);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_parameter_midi_channel(%i, %i, %i) - could not find plugin", pluginId, parameter_id, channel);
-}
-
-void set_parameter_midi_cc(unsigned short pluginId, uint32_t parameter_id, int16_t cc)
-{
- qDebug("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i)", pluginId, parameter_id, cc);
- CARLA_ASSERT(standalone.engine);
- CARLA_ASSERT(cc >= -1 && cc <= 0x5F);
-
- if (cc < -1)
- {
- cc = -1;
- }
- else if (cc > 0x5F) // 95
- {
- qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - invalid cc number", pluginId, parameter_id, cc);
- return;
- }
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (parameter_id < plugin->parameterCount())
- return plugin->setParameterMidiCC(parameter_id, cc, true, false);
-
- qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - parameter_id out of bounds", pluginId, parameter_id, cc);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_parameter_midi_cc(%i, %i, %i) - could not find plugin", pluginId, parameter_id, cc);
-}
-
-void set_program(unsigned short pluginId, uint32_t program_id)
-{
- qDebug("CarlaBackendStandalone::set_program(%i, %i)", pluginId, program_id);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (program_id < plugin->programCount())
- return plugin->setProgram(program_id, true, true, false, true);
-
- qCritical("CarlaBackendStandalone::set_program(%i, %i) - program_id out of bounds", pluginId, program_id);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_program(%i, %i) - could not find plugin", pluginId, program_id);
-}
-
-void set_midi_program(unsigned short pluginId, uint32_t midi_program_id)
-{
- qDebug("CarlaBackendStandalone::set_midi_program(%i, %i)", pluginId, midi_program_id);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (midi_program_id < plugin->midiProgramCount())
- return plugin->setMidiProgram(midi_program_id, true, true, false, true);
-
- qCritical("CarlaBackendStandalone::set_midi_program(%i, %i) - midi_program_id out of bounds", pluginId, midi_program_id);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_midi_program(%i, %i) - could not find plugin", pluginId, midi_program_id);
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void set_custom_data(unsigned short pluginId, const char* type, const char* key, const char* value)
-{
- qDebug("CarlaBackendStandalone::set_custom_data(%i, \"%s\", \"%s\", \"%s\")", pluginId, type, key, value);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setCustomData(type, key, value, true);
-
- qCritical("CarlaBackendStandalone::set_custom_data(%i, \"%s\", \"%s\", \"%s\") - could not find plugin", pluginId, type, key, value);
-}
-
-void set_chunk_data(unsigned short pluginId, const char* chunk_data)
-{
- qDebug("CarlaBackendStandalone::set_chunk_data(%i, \"%s\")", pluginId, chunk_data);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- {
- if (plugin->hints() & CarlaBackend::PLUGIN_USES_CHUNKS)
- return plugin->setChunkData(chunk_data);
-
- qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - plugin does not support chunks", pluginId, chunk_data);
- return;
- }
-
- qCritical("CarlaBackendStandalone::set_chunk_data(%i, \"%s\") - could not find plugin", pluginId, chunk_data);
-}
-
-void set_gui_container(unsigned short pluginId, uintptr_t gui_addr)
-{
- qDebug("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ")", pluginId, gui_addr);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->setGuiContainer((GuiContainer*)CarlaBackend::getPointerFromAddress(gui_addr));
-
- qCritical("CarlaBackendStandalone::set_gui_container(%i, " P_UINTPTR ") - could not find plugin", pluginId, gui_addr);
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void show_gui(unsigned short pluginId, bool yesno)
-{
- qDebug("CarlaBackendStandalone::show_gui(%i, %s)", pluginId, bool2str(yesno));
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->showGui(yesno);
-
- qCritical("CarlaBackendStandalone::show_gui(%i, %s) - could not find plugin", pluginId, bool2str(yesno));
-}
-
-void idle_guis()
-{
- CARLA_ASSERT(standalone.engine);
-
- if (standalone.engine)
- standalone.engine->idlePluginGuis();
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void send_midi_note(unsigned short pluginId, uint8_t channel, uint8_t note, uint8_t velocity)
-{
- qDebug("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i)", pluginId, channel, note, velocity);
- CARLA_ASSERT(standalone.engine);
-
- if (! (standalone.engine && standalone.engine->isRunning()))
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->sendMidiSingleNote(channel, note, velocity, true, true, false);
-
- qCritical("CarlaBackendStandalone::send_midi_note(%i, %i, %i, %i) - could not find plugin", pluginId, channel, note, velocity);
-}
-
-void prepare_for_save(unsigned short pluginId)
-{
- qDebug("CarlaBackendStandalone::prepare_for_save(%i)", pluginId);
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return;
-
- CarlaBackend::CarlaPlugin* const plugin = standalone.engine->getPlugin(pluginId);
-
- if (plugin)
- return plugin->prepareForSave();
-
- qCritical("CarlaBackendStandalone::prepare_for_save(%i) - could not find plugin", pluginId);
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-uint32_t get_buffer_size()
-{
- qDebug("CarlaBackendStandalone::get_buffer_size()");
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0;
-
- return standalone.engine->getBufferSize();
-}
-
-double get_sample_rate()
-{
- qDebug("CarlaBackendStandalone::get_sample_rate()");
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return 0.0;
-
- return standalone.engine->getSampleRate();
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-const char* get_last_error()
-{
- qDebug("CarlaBackendStandalone::get_last_error()");
-
- if (standalone.engine)
- return standalone.engine->getLastError();
-
- return standalone.lastError;
-}
-
-const char* get_host_osc_url()
-{
- qDebug("CarlaBackendStandalone::get_host_osc_url()");
- CARLA_ASSERT(standalone.engine);
-
- if (! standalone.engine)
- return nullptr;
-
- return standalone.engine->getOscServerPathTCP();
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-void set_callback_function(CarlaBackend::CallbackFunc func)
-{
- qDebug("CarlaBackendStandalone::set_callback_function(%p)", func);
-
- standalone.callback = func;
-
- if (standalone.engine)
- standalone.engine->setCallback(func, nullptr);
-}
-
-void set_option(CarlaBackend::OptionsType option, int value, const char* value_str)
-{
- qDebug("CarlaBackendStandalone::set_option(%s, %i, \"%s\")", CarlaBackend::OptionsType2Str(option), value, value_str);
-
- if (standalone.engine)
- standalone.engine->setOption(option, value, value_str);
-
- switch (option)
- {
- case CarlaBackend::OPTION_PROCESS_NAME:
- standalone.procName = value_str;
- break;
-
- case CarlaBackend::OPTION_PROCESS_MODE:
- if (value < CarlaBackend::PROCESS_MODE_SINGLE_CLIENT || value > CarlaBackend::PROCESS_MODE_PATCHBAY)
- return qCritical("CarlaBackendStandalone::set_option(%s, %i, \"%s\") - invalid value", OptionsType2Str(option), value, value_str);
-
- standalone.options.processMode = static_cast(value);
- break;
-
- case CarlaBackend::OPTION_PROCESS_HIGH_PRECISION:
- standalone.options.processHighPrecision = value;
- break;
-
- case CarlaBackend::OPTION_MAX_PARAMETERS:
- standalone.options.maxParameters = (value > 0) ? value : CarlaBackend::MAX_PARAMETERS;
- break;
-
- case CarlaBackend::OPTION_PREFERRED_BUFFER_SIZE:
- standalone.options.preferredBufferSize = value;
- break;
-
- case CarlaBackend::OPTION_PREFERRED_SAMPLE_RATE:
- standalone.options.preferredSampleRate = value;
- break;
-
- case CarlaBackend::OPTION_FORCE_STEREO:
- standalone.options.forceStereo = value;
- break;
-
- case CarlaBackend::OPTION_USE_DSSI_VST_CHUNKS:
- standalone.options.useDssiVstChunks = value;
- break;
-
- case CarlaBackend::OPTION_PREFER_PLUGIN_BRIDGES:
- standalone.options.preferPluginBridges = value;
- break;
-
- case CarlaBackend::OPTION_PREFER_UI_BRIDGES:
- standalone.options.preferUiBridges = value;
- break;
-
- case CarlaBackend::OPTION_OSC_UI_TIMEOUT:
- standalone.options.oscUiTimeout = value;
- break;
-
- case CarlaBackend::OPTION_PATH_BRIDGE_POSIX32:
- standalone.options.bridge_posix32 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_POSIX64:
- standalone.options.bridge_posix64 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_WIN32:
- standalone.options.bridge_win32 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_WIN64:
- standalone.options.bridge_win64 = value_str;
- break;
-
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_GTK2:
- standalone.options.bridge_lv2gtk2 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_GTK3:
- standalone.options.bridge_lv2gtk3 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_QT4:
- standalone.options.bridge_lv2qt4 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_QT5:
- standalone.options.bridge_lv2qt5 = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_COCOA:
- standalone.options.bridge_lv2cocoa = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_WINDOWS:
- standalone.options.bridge_lv2win = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_LV2_X11:
- standalone.options.bridge_lv2x11 = value_str;
- break;
-
- case CarlaBackend::OPTION_PATH_BRIDGE_VST_COCOA:
- standalone.options.bridge_vstcocoa = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_VST_HWND:
- standalone.options.bridge_vsthwnd = value_str;
- break;
- case CarlaBackend::OPTION_PATH_BRIDGE_VST_X11:
- standalone.options.bridge_vstx11 = value_str;
- break;
- }
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-#define NSM_API_VERSION_MAJOR 1
-#define NSM_API_VERSION_MINOR 0
-
-class CarlaNSM
-{
-public:
- CarlaNSM()
- {
- m_controlAddr = nullptr;
- m_serverThread = nullptr;
- m_isOpened = false;
- m_isSaved = false;
- }
-
- ~CarlaNSM()
- {
- if (m_controlAddr)
- lo_address_free(m_controlAddr);
-
- if (m_serverThread)
- {
- lo_server_thread_stop(m_serverThread);
- lo_server_thread_del_method(m_serverThread, "/reply", "ssss");
- lo_server_thread_del_method(m_serverThread, "/nsm/client/open", "sss");
- lo_server_thread_del_method(m_serverThread, "/nsm/client/save", "");
- lo_server_thread_free(m_serverThread);
- }
- }
-
- void announce(const char* const url, const int pid)
- {
- lo_address addr = lo_address_new_from_url(url);
- int proto = lo_address_get_protocol(addr);
-
- if (! m_serverThread)
- {
- // create new OSC thread
- m_serverThread = lo_server_thread_new_with_proto(nullptr, proto, error_handler);
-
- // register message handlers and start OSC thread
- lo_server_thread_add_method(m_serverThread, "/reply", "ssss", _reply_handler, this);
- lo_server_thread_add_method(m_serverThread, "/nsm/client/open", "sss", _nsm_open_handler, this);
- lo_server_thread_add_method(m_serverThread, "/nsm/client/save", "", _nsm_save_handler, this);
- lo_server_thread_start(m_serverThread);
- }
-
- lo_send_from(addr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
- "Carla", ":switch:", "carla", NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid);
-
- lo_address_free(addr);
- }
-
- void replyOpen()
- {
- m_isOpened = true;
- }
-
- void replySave()
- {
- m_isSaved = true;
- }
-
-protected:
- int reply_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
- {
- qDebug("CarlaNSM::reply_handler(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
-
- m_controlAddr = lo_address_new_from_url(lo_address_get_url(lo_message_get_source(msg)));
-
- const char* const method = &argv[0]->s;
-
- if (strcmp(method, "/nsm/server/announce") == 0 && standalone.callback)
- standalone.callback(nullptr, CarlaBackend::CALLBACK_NSM_ANNOUNCE, 0, 0, 0, 0.0, nullptr); // FIXME?
-
- return 0;
- }
-
- int nsm_open_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
- {
- qDebug("CarlaNSM::nsm_open_handler(\"%s\", \"%s\", %p, %i, %p)", path, types, argv, argc, msg);
-
- if (! standalone.callback)
- return 1;
-
- const char* const projectPath = &argv[0]->s;
- const char* const clientId = &argv[2]->s;
-
- standalone.callback(nullptr, CarlaBackend::CALLBACK_NSM_OPEN1, 0, 0, 0, 0.0, clientId);
- standalone.callback(nullptr, CarlaBackend::CALLBACK_NSM_OPEN2, 0, 0, 0, 0.0, projectPath);
-
- for (int i=0; i < 30 && ! m_isOpened; i++)
- carla_msleep(100);
-
- if (m_controlAddr)
- lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/open", "OK");
-
- return 0;
- }
-
- int nsm_save_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg)
- {
- qDebug("CarlaNSM::nsm_save_handler(\"%s\", \"%s\", %p, %i, %p)", path, types, argv, argc, msg);
-
- if (! standalone.callback)
- return 1;
-
- standalone.callback(nullptr, CarlaBackend::CALLBACK_NSM_SAVE, 0, 0, 0, 0.0, nullptr);
-
- for (int i=0; i < 30 && ! m_isSaved; i++)
- carla_msleep(100);
-
- if (m_controlAddr)
- lo_send_from(m_controlAddr, lo_server_thread_get_server(m_serverThread), LO_TT_IMMEDIATE, "/reply", "ss", "/nsm/client/save", "OK");
-
- return 0;
- }
-
-private:
- lo_address m_controlAddr;
- lo_server_thread m_serverThread;
- bool m_isOpened, m_isSaved;
-
- static int _reply_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
- {
- CARLA_ASSERT(data);
- CarlaNSM* const _this_ = (CarlaNSM*)data;
- return _this_->reply_handler(path, types, argv, argc, msg);
- }
-
- static int _nsm_open_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
- {
- CARLA_ASSERT(data);
- CarlaNSM* const _this_ = (CarlaNSM*)data;
- return _this_->nsm_open_handler(path, types, argv, argc, msg);
- }
-
- static int _nsm_save_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const data)
- {
- CARLA_ASSERT(data);
- CarlaNSM* const _this_ = (CarlaNSM*)data;
- return _this_->nsm_save_handler(path, types, argv, argc, msg);
- }
-
- static void error_handler(const int num, const char* const msg, const char* const path)
- {
- qCritical("CarlaNSM::error_handler(%i, \"%s\", \"%s\")", num, msg, path);
- }
-};
-
-static CarlaNSM carlaNSM;
-
-void nsm_announce(const char* url, int pid)
-{
- carlaNSM.announce(url, pid);
-}
-
-void nsm_reply_open()
-{
- carlaNSM.replyOpen();
-}
-
-void nsm_reply_save()
-{
- carlaNSM.replySave();
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-#if 0 //def QTCREATOR_TEST
-
-#include
-#include
-
-QDialog* vstGui = nullptr;
-
-void main_callback(void* ptr, CarlaBackend::CallbackType action, unsigned short pluginId, int value1, int value2, double value3)
-{
- switch (action)
- {
- case CarlaBackend::CALLBACK_SHOW_GUI:
- if (vstGui && ! value1)
- vstGui->close();
- break;
- case CarlaBackend::CALLBACK_RESIZE_GUI:
- vstGui->setFixedSize(value1, value2);
- break;
- default:
- break;
- }
-
- Q_UNUSED(ptr);
- Q_UNUSED(pluginId);
- Q_UNUSED(value3);
-}
-
-void run_tests_standalone(short idMax)
-{
- for (short id = 0; id <= idMax; id++)
- {
- qDebug("------------------- TEST @%i: non-parameter calls --------------------", id);
- get_plugin_info(id);
- get_audio_port_count_info(id);
- get_midi_port_count_info(id);
- get_parameter_count_info(id);
- get_gui_info(id);
- get_chunk_data(id);
- get_parameter_count(id);
- get_program_count(id);
- get_midi_program_count(id);
- get_custom_data_count(id);
- get_real_plugin_name(id);
- get_current_program_index(id);
- get_current_midi_program_index(id);
-
- qDebug("------------------- TEST @%i: parameter calls [-1] --------------------", id);
- get_parameter_info(id, -1);
- get_parameter_scalepoint_info(id, -1, -1);
- get_parameter_data(id, -1);
- get_parameter_ranges(id, -1);
- get_midi_program_data(id, -1);
- get_custom_data(id, -1);
- get_parameter_text(id, -1);
- get_program_name(id, -1);
- get_midi_program_name(id, -1);
- get_default_parameter_value(id, -1);
- get_current_parameter_value(id, -1);
- get_input_peak_value(id, -1);
- get_output_peak_value(id, -1);
-
- qDebug("------------------- TEST @%i: parameter calls [0] --------------------", id);
- get_parameter_info(id, 0);
- get_parameter_scalepoint_info(id, 0, -1);
- get_parameter_scalepoint_info(id, 0, 0);
- get_parameter_data(id, 0);
- get_parameter_ranges(id, 0);
- get_midi_program_data(id, 0);
- get_custom_data(id, 0);
- get_parameter_text(id, 0);
- get_program_name(id, 0);
- get_midi_program_name(id, 0);
- get_default_parameter_value(id, 0);
- get_current_parameter_value(id, 0);
- get_input_peak_value(id, 0);
- get_input_peak_value(id, 1);
- get_input_peak_value(id, 2);
- get_output_peak_value(id, 0);
- get_output_peak_value(id, 1);
- get_output_peak_value(id, 2);
-
- qDebug("------------------- TEST @%i: set extra data --------------------", id);
- set_custom_data(id, CarlaBackend::CUSTOM_DATA_STRING, "", "");
- set_chunk_data(id, nullptr);
- set_gui_container(id, (uintptr_t)1);
-
- qDebug("------------------- TEST @%i: gui stuff --------------------", id);
- show_gui(id, false);
- show_gui(id, true);
- show_gui(id, true);
-
- idle_guis();
- idle_guis();
- idle_guis();
-
- qDebug("------------------- TEST @%i: other --------------------", id);
- send_midi_note(id, 15, 127, 127);
- send_midi_note(id, 0, 0, 0);
-
- prepare_for_save(id);
- prepare_for_save(id);
- prepare_for_save(id);
- }
-}
-
-int main(int argc, char* argv[])
-{
- using namespace CarlaBackend;
-
- // Qt app
- QApplication app(argc, argv);
-
- // Qt gui (for vst)
- vstGui = new QDialog(nullptr);
-
- // set callback and options
- set_callback_function(main_callback);
- set_option(OPTION_PREFER_UI_BRIDGES, 0, nullptr);
- //set_option(OPTION_PROCESS_MODE, PROCESS_MODE_CONTINUOUS_RACK, nullptr);
-
- // start engine
- if (! engine_init("JACK", "carla_demo"))
- {
- qCritical("failed to start backend engine, reason:\n%s", get_last_error());
- delete vstGui;
- return 1;
- }
-
- short id_ladspa = add_plugin(BINARY_NATIVE, PLUGIN_LADSPA, "/usr/lib/ladspa/LEET_eqbw2x2.so", "LADSPA plug name, test long name - "
- "------- name ------------ name2 ----------- name3 ------------ name4 ------------ name5 ---------- name6", "leet_equalizer_bw2x2", nullptr);
-
- short id_dssi = add_plugin(BINARY_NATIVE, PLUGIN_DSSI, "/usr/lib/dssi/fluidsynth-dssi.so", "DSSI pname, short-utf8 _ \xAE", "FluidSynth-DSSI", (void*)"/usr/lib/dssi/fluidsynth-dssi/FluidSynth-DSSI_gtk");
- short id_native = add_plugin(BINARY_NATIVE, PLUGIN_INTERNAL, "", "ZynHere", "zynaddsubfx", nullptr);
-
- //short id_lv2 = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
-
- //short id_vst = add_plugin(BINARY_NATIVE, PLUGIN_LV2, "FILENAME", "HAHA name!!!", "http://studionumbersix.com/foo/lv2/yc20", nullptr);
-
- if (id_ladspa < 0 || id_dssi < 0 || id_native < 0)
- {
- qCritical("failed to start load plugins, reason:\n%s", get_last_error());
- delete vstGui;
- return 1;
- }
-
- //const GuiInfo* const guiInfo = get_gui_info(id);
- //if (guiInfo->type == CarlaBackend::GUI_INTERNAL_QT4 || guiInfo->type == CarlaBackend::GUI_INTERNAL_X11)
- //{
- // set_gui_data(id, 0, (uintptr_t)gui);
- //gui->show();
- //}
-
- // activate
- set_active(id_ladspa, true);
- set_active(id_dssi, true);
- set_active(id_native, true);
-
- // start guis
- show_gui(id_dssi, true);
- carla_sleep(1);
-
- // do tests
- run_tests_standalone(id_dssi+1);
-
- // lock
- app.exec();
-
- delete vstGui;
- vstGui = nullptr;
-
- remove_plugin(id_ladspa);
- remove_plugin(id_dssi);
- remove_plugin(id_native);
- engine_close();
-
- return 0;
-}
-
-#endif
diff --git a/c++/carla-backend/carla_backend_standalone.hpp b/c++/carla-backend/carla_backend_standalone.hpp
deleted file mode 100644
index 7147c8a..0000000
--- a/c++/carla-backend/carla_backend_standalone.hpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Carla Backend
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BACKEND_STANDALONE_H
-#define CARLA_BACKEND_STANDALONE_H
-
-#include
-
-#include "carla_backend.hpp"
-
-// TODO - create struct for internal plugin info
-// TODO - dont strdup() on const-char* returns, use static char[STR_MAX]
-
-/*!
- * @defgroup CarlaBackendStandalone Carla Backend Standalone
- *
- * The Carla Backend Standalone API
- *
- * @{
- */
-
-struct PluginInfo {
- CarlaBackend::PluginType type;
- CarlaBackend::PluginCategory category;
- unsigned int hints;
- const char* binary;
- const char* name;
- const char* label;
- const char* maker;
- const char* copyright;
- long uniqueId;
-
- PluginInfo()
- : type(CarlaBackend::PLUGIN_NONE),
- category(CarlaBackend::PLUGIN_CATEGORY_NONE),
- hints(0x0),
- binary(nullptr),
- name(nullptr),
- label(nullptr),
- maker(nullptr),
- copyright(nullptr),
- uniqueId(0) {}
-};
-
-struct PortCountInfo {
- uint32_t ins;
- uint32_t outs;
- uint32_t total;
-
- PortCountInfo()
- : ins(0),
- outs(0),
- total(0) {}
-};
-
-struct ParameterInfo {
- const char* name;
- const char* symbol;
- const char* unit;
- uint32_t scalePointCount;
-
- ParameterInfo()
- : name(nullptr),
- symbol(nullptr),
- unit(nullptr),
- scalePointCount(0) {}
-};
-
-struct ScalePointInfo {
- double value;
- const char* label;
-
- ScalePointInfo()
- : value(0.0),
- label(nullptr) {}
-};
-
-struct GuiInfo {
- CarlaBackend::GuiType type;
- bool resizable;
-
- GuiInfo()
- : type(CarlaBackend::GUI_NONE),
- resizable(false) {}
-};
-
-CARLA_EXPORT const char* get_extended_license_text();
-
-CARLA_EXPORT unsigned int get_engine_driver_count();
-CARLA_EXPORT const char* get_engine_driver_name(unsigned int index);
-
-CARLA_EXPORT unsigned int get_internal_plugin_count();
-CARLA_EXPORT const PluginInfo* get_internal_plugin_info(unsigned int pluginId);
-
-CARLA_EXPORT bool engine_init(const char* driverName, const char* clientName);
-CARLA_EXPORT bool engine_close();
-CARLA_EXPORT bool is_engine_running();
-
-CARLA_EXPORT short add_plugin(CarlaBackend::BinaryType btype, CarlaBackend::PluginType ptype, const char* filename, const char* name, const char* label, void* extraStuff);
-CARLA_EXPORT bool remove_plugin(unsigned short pluginId);
-
-CARLA_EXPORT const PluginInfo* get_plugin_info(unsigned short pluginId);
-CARLA_EXPORT const PortCountInfo* get_audio_port_count_info(unsigned short pluginId);
-CARLA_EXPORT const PortCountInfo* get_midi_port_count_info(unsigned short pluginId);
-CARLA_EXPORT const PortCountInfo* get_parameter_count_info(unsigned short pluginId);
-CARLA_EXPORT const ParameterInfo* get_parameter_info(unsigned short plugin_id, uint32_t parameterId);
-CARLA_EXPORT const ScalePointInfo* get_parameter_scalepoint_info(unsigned short pluginId, uint32_t parameterId, uint32_t scalePointId);
-CARLA_EXPORT const GuiInfo* get_gui_info(unsigned short pluginId);
-
-CARLA_EXPORT const CarlaBackend::ParameterData* get_parameter_data(unsigned short pluginId, uint32_t parameterId);
-CARLA_EXPORT const CarlaBackend::ParameterRanges* get_parameter_ranges(unsigned short pluginId, uint32_t parameterId);
-CARLA_EXPORT const CarlaBackend::MidiProgramData* get_midi_program_data(unsigned short pluginId, uint32_t midiProgramId);
-CARLA_EXPORT const CarlaBackend::CustomData* get_custom_data(unsigned short pluginId, uint32_t customDataId);
-CARLA_EXPORT const char* get_chunk_data(unsigned short pluginId);
-
-CARLA_EXPORT uint32_t get_parameter_count(unsigned short pluginId);
-CARLA_EXPORT uint32_t get_program_count(unsigned short pluginId);
-CARLA_EXPORT uint32_t get_midi_program_count(unsigned short pluginId);
-CARLA_EXPORT uint32_t get_custom_data_count(unsigned short pluginId);
-
-CARLA_EXPORT const char* get_parameter_text(unsigned short pluginId, uint32_t parameterId);
-CARLA_EXPORT const char* get_program_name(unsigned short pluginId, uint32_t programId);
-CARLA_EXPORT const char* get_midi_program_name(unsigned short pluginId, uint32_t midiProgramId);
-CARLA_EXPORT const char* get_real_plugin_name(unsigned short pluginId);
-
-CARLA_EXPORT int32_t get_current_program_index(unsigned short pluginId);
-CARLA_EXPORT int32_t get_current_midi_program_index(unsigned short pluginId);
-
-CARLA_EXPORT double get_default_parameter_value(unsigned short pluginId, uint32_t parameterId);
-CARLA_EXPORT double get_current_parameter_value(unsigned short pluginId, uint32_t parameterId);
-
-CARLA_EXPORT double get_input_peak_value(unsigned short pluginId, unsigned short portId);
-CARLA_EXPORT double get_output_peak_value(unsigned short pluginId, unsigned short portId);
-
-CARLA_EXPORT void set_active(unsigned short pluginId, bool onOff);
-CARLA_EXPORT void set_drywet(unsigned short pluginId, double value);
-CARLA_EXPORT void set_volume(unsigned short pluginId, double value);
-CARLA_EXPORT void set_balance_left(unsigned short pluginId, double value);
-CARLA_EXPORT void set_balance_right(unsigned short pluginId, double value);
-
-CARLA_EXPORT void set_parameter_value(unsigned short pluginId, uint32_t parameterId, double value);
-CARLA_EXPORT void set_parameter_midi_channel(unsigned short pluginId, uint32_t parameterId, uint8_t channel);
-CARLA_EXPORT void set_parameter_midi_cc(unsigned short pluginId, uint32_t parameterId, int16_t cc);
-CARLA_EXPORT void set_program(unsigned short pluginId, uint32_t programId);
-CARLA_EXPORT void set_midi_program(unsigned short pluginId, uint32_t midiProgramId);
-
-CARLA_EXPORT void set_custom_data(unsigned short pluginId, const char* type, const char* key, const char* value);
-CARLA_EXPORT void set_chunk_data(unsigned short pluginId, const char* chunkData);
-CARLA_EXPORT void set_gui_container(unsigned short pluginId, uintptr_t guiAddr);
-
-CARLA_EXPORT void show_gui(unsigned short pluginId, bool yesNo);
-CARLA_EXPORT void idle_guis();
-
-CARLA_EXPORT void send_midi_note(unsigned short pluginId, uint8_t channel, uint8_t note, uint8_t velocity);
-CARLA_EXPORT void prepare_for_save(unsigned short pluginId);
-
-CARLA_EXPORT uint32_t get_buffer_size();
-CARLA_EXPORT double get_sample_rate();
-
-CARLA_EXPORT const char* get_last_error();
-CARLA_EXPORT const char* get_host_osc_url();
-
-CARLA_EXPORT void set_callback_function(CarlaBackend::CallbackFunc func);
-CARLA_EXPORT void set_option(CarlaBackend::OptionsType option, int value, const char* valueStr);
-
-CARLA_EXPORT void nsm_announce(const char* url, int pid);
-CARLA_EXPORT void nsm_reply_open();
-CARLA_EXPORT void nsm_reply_save();
-
-/**@}*/
-
-#endif // CARLA_BACKEND_STANDALONE_H
diff --git a/c++/carla-backend/carla_backend_utils.hpp b/c++/carla-backend/carla_backend_utils.hpp
deleted file mode 100644
index 22c884f..0000000
--- a/c++/carla-backend/carla_backend_utils.hpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Carla Backend
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BACKEND_UTILS_HPP
-#define CARLA_BACKEND_UTILS_HPP
-
-#include "carla_backend.hpp"
-#include "carla_utils.hpp"
-
-CARLA_BACKEND_START_NAMESPACE
-
-/*!
- * @defgroup CarlaBackendUtils Carla Backend Utils
- *
- * Carla Backend Utils
- *
- * @{
- */
-
-static inline
-const char* BinaryType2Str(const BinaryType& type)
-{
- switch (type)
- {
- case BINARY_NONE:
- return "BINARY_NONE";
- case BINARY_POSIX32:
- return "BINARY_POSIX32";
- case BINARY_POSIX64:
- return "BINARY_POSIX64";
- case BINARY_WIN32:
- return "BINARY_WIN32";
- case BINARY_WIN64:
- return "BINARY_WIN64";
- case BINARY_OTHER:
- return "BINARY_OTHER";
- }
-
- qWarning("CarlaBackend::BinaryType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* PluginType2Str(const PluginType& type)
-{
- switch (type)
- {
- case PLUGIN_NONE:
- return "PLUGIN_NONE";
- case PLUGIN_INTERNAL:
- return "PLUGIN_INTERNAL";
- case PLUGIN_LADSPA:
- return "PLUGIN_LADSPA";
- case PLUGIN_DSSI:
- return "PLUGIN_DSSI";
- case PLUGIN_LV2:
- return "PLUGIN_LV2";
- case PLUGIN_VST:
- return "PLUGIN_VST";
- case PLUGIN_GIG:
- return "PLUGIN_GIG";
- case PLUGIN_SF2:
- return "PLUGIN_SF2";
- case PLUGIN_SFZ:
- return "PLUGIN_SFZ";
- }
-
- qWarning("CarlaBackend::PluginType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* PluginCategory2Str(const PluginCategory& category)
-{
- switch (category)
- {
- case PLUGIN_CATEGORY_NONE:
- return "PLUGIN_CATEGORY_NONE";
- case PLUGIN_CATEGORY_SYNTH:
- return "PLUGIN_CATEGORY_SYNTH";
- case PLUGIN_CATEGORY_DELAY:
- return "PLUGIN_CATEGORY_DELAY";
- case PLUGIN_CATEGORY_EQ:
- return "PLUGIN_CATEGORY_EQ";
- case PLUGIN_CATEGORY_FILTER:
- return "PLUGIN_CATEGORY_FILTER";
- case PLUGIN_CATEGORY_DYNAMICS:
- return "PLUGIN_CATEGORY_DYNAMICS";
- case PLUGIN_CATEGORY_MODULATOR:
- return "PLUGIN_CATEGORY_MODULATOR";
- case PLUGIN_CATEGORY_UTILITY:
- return "PLUGIN_CATEGORY_UTILITY";
- case PLUGIN_CATEGORY_OTHER:
- return "PLUGIN_CATEGORY_OTHER";
- }
-
- qWarning("CarlaBackend::PluginCategory2Str(%i) - invalid category", category);
- return nullptr;
-}
-
-static inline
-const char* ParameterType2Str(const ParameterType& type)
-{
- switch (type)
- {
- case PARAMETER_UNKNOWN:
- return "PARAMETER_UNKNOWN";
- case PARAMETER_INPUT:
- return "PARAMETER_INPUT";
- case PARAMETER_OUTPUT:
- return "PARAMETER_OUTPUT";
- case PARAMETER_LATENCY:
- return "PARAMETER_LATENCY";
- case PARAMETER_SAMPLE_RATE:
- return "PARAMETER_SAMPLE_RATE";
- case PARAMETER_LV2_FREEWHEEL:
- return "PARAMETER_LV2_FREEWHEEL";
- case PARAMETER_LV2_TIME:
- return "PARAMETER_LV2_TIME";
- }
-
- qWarning("CarlaBackend::ParameterType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* InternalParametersIndex2Str(const InternalParametersIndex& index)
-{
- switch (index)
- {
- case PARAMETER_NULL:
- return "PARAMETER_NULL";
- case PARAMETER_ACTIVE:
- return "PARAMETER_ACTIVE";
- case PARAMETER_DRYWET:
- return "PARAMETER_DRYWET";
- case PARAMETER_VOLUME:
- return "PARAMETER_VOLUME";
- case PARAMETER_BALANCE_LEFT:
- return "PARAMETER_BALANCE_LEFT";
- case PARAMETER_BALANCE_RIGHT:
- return "PARAMETER_BALANCE_RIGHT";
- }
-
- qWarning("CarlaBackend::InternalParametersIndex2Str(%i) - invalid index", index);
- return nullptr;
-}
-
-static inline
-const char* GuiType2Str(const GuiType& type)
-{
- switch (type)
- {
- case GUI_NONE:
- return "GUI_NONE";
- case GUI_INTERNAL_QT4:
- return "GUI_INTERNAL_QT4";
- case GUI_INTERNAL_COCOA:
- return "GUI_INTERNAL_COCOA";
- case GUI_INTERNAL_HWND:
- return "GUI_INTERNAL_HWND";
- case GUI_INTERNAL_X11:
- return "GUI_INTERNAL_X11";
- case GUI_EXTERNAL_LV2:
- return "GUI_EXTERNAL_LV2";
- case GUI_EXTERNAL_SUIL:
- return "GUI_EXTERNAL_SUIL";
- case GUI_EXTERNAL_OSC:
- return "GUI_EXTERNAL_OSC";
- }
-
- qWarning("CarlaBackend::GuiType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* OptionsType2Str(const OptionsType& type)
-{
- switch (type)
- {
- case OPTION_PROCESS_NAME:
- return "OPTION_PROCESS_NAME";
- case OPTION_PROCESS_MODE:
- return "OPTION_PROCESS_MODE";
- case OPTION_PROCESS_HIGH_PRECISION:
- return "OPTION_PROCESS_HIGH_PRECISION";
- case OPTION_MAX_PARAMETERS:
- return "OPTION_MAX_PARAMETERS";
- case OPTION_PREFERRED_BUFFER_SIZE:
- return "OPTION_PREFERRED_BUFFER_SIZE";
- case OPTION_PREFERRED_SAMPLE_RATE:
- return "OPTION_PREFERRED_SAMPLE_RATE";
- case OPTION_FORCE_STEREO:
- return "OPTION_FORCE_STEREO";
- case OPTION_USE_DSSI_VST_CHUNKS:
- return "OPTION_USE_DSSI_VST_CHUNKS";
- case OPTION_PREFER_PLUGIN_BRIDGES:
- return "OPTION_PREFER_PLUGIN_BRIDGES";
- case OPTION_PREFER_UI_BRIDGES:
- return "OPTION_PREFER_UI_BRIDGES";
- case OPTION_OSC_UI_TIMEOUT:
- return "OPTION_OSC_UI_TIMEOUT";
- case OPTION_PATH_BRIDGE_POSIX32:
- return "OPTION_PATH_BRIDGE_POSIX32";
- case OPTION_PATH_BRIDGE_POSIX64:
- return "OPTION_PATH_BRIDGE_POSIX64";
- case OPTION_PATH_BRIDGE_WIN32:
- return "OPTION_PATH_BRIDGE_WIN32";
- case OPTION_PATH_BRIDGE_WIN64:
- return "OPTION_PATH_BRIDGE_WIN64";
- case OPTION_PATH_BRIDGE_LV2_GTK2:
- return "OPTION_PATH_BRIDGE_LV2_GTK2";
- case OPTION_PATH_BRIDGE_LV2_GTK3:
- return "OPTION_PATH_BRIDGE_LV2_GTK3";
- case OPTION_PATH_BRIDGE_LV2_QT4:
- return "OPTION_PATH_BRIDGE_LV2_QT4";
- case OPTION_PATH_BRIDGE_LV2_QT5:
- return "OPTION_PATH_BRIDGE_LV2_QT5";
- case OPTION_PATH_BRIDGE_LV2_COCOA:
- return "OPTION_PATH_BRIDGE_LV2_COCOA";
- case OPTION_PATH_BRIDGE_LV2_WINDOWS:
- return "OPTION_PATH_BRIDGE_LV2_WINDOWS";
- case OPTION_PATH_BRIDGE_LV2_X11:
- return "OPTION_PATH_BRIDGE_LV2_X11";
- case OPTION_PATH_BRIDGE_VST_COCOA:
- return "OPTION_PATH_BRIDGE_VST_COCOA";
- case OPTION_PATH_BRIDGE_VST_HWND:
- return "OPTION_PATH_BRIDGE_VST_HWND";
- case OPTION_PATH_BRIDGE_VST_X11:
- return "OPTION_PATH_BRIDGE_VST_X11";
- }
-
- qWarning("CarlaBackend::OptionsType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* CallbackType2Str(const CallbackType& type)
-{
- switch (type)
- {
- case CALLBACK_DEBUG:
- return "CALLBACK_DEBUG";
- case CALLBACK_PARAMETER_VALUE_CHANGED:
- return "CALLBACK_PARAMETER_VALUE_CHANGED";
- case CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
- return "CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED";
- case CALLBACK_PARAMETER_MIDI_CC_CHANGED:
- return "CALLBACK_PARAMETER_MIDI_CC_CHANGED";
- case CALLBACK_PROGRAM_CHANGED:
- return "CALLBACK_PROGRAM_CHANGED";
- case CALLBACK_MIDI_PROGRAM_CHANGED:
- return "CALLBACK_MIDI_PROGRAM_CHANGED";
- case CALLBACK_NOTE_ON:
- return "CALLBACK_NOTE_ON";
- case CALLBACK_NOTE_OFF:
- return "CALLBACK_NOTE_OFF";
- case CALLBACK_SHOW_GUI:
- return "CALLBACK_SHOW_GUI";
- case CALLBACK_RESIZE_GUI:
- return "CALLBACK_RESIZE_GUI";
- case CALLBACK_UPDATE:
- return "CALLBACK_UPDATE";
- case CALLBACK_RELOAD_INFO:
- return "CALLBACK_RELOAD_INFO";
- case CALLBACK_RELOAD_PARAMETERS:
- return "CALLBACK_RELOAD_PARAMETERS";
- case CALLBACK_RELOAD_PROGRAMS:
- return "CALLBACK_RELOAD_PROGRAMS";
- case CALLBACK_RELOAD_ALL:
- return "CALLBACK_RELOAD_ALL";
- case CALLBACK_NSM_ANNOUNCE:
- return "CALLBACK_NSM_ANNOUNCE";
- case CALLBACK_NSM_OPEN1:
- return "CALLBACK_NSM_OPEN1";
- case CALLBACK_NSM_OPEN2:
- return "CALLBACK_NSM_OPEN2";
- case CALLBACK_NSM_SAVE:
- return "CALLBACK_NSM_SAVE";
- case CALLBACK_ERROR:
- return "CALLBACK_ERROR";
- case CALLBACK_QUIT:
- return "CALLBACK_QUIT";
- }
-
- qWarning("CarlaBackend::CallbackType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-static inline
-const char* ProcessMode2Str(const ProcessMode& mode)
-{
- switch (mode)
- {
- case PROCESS_MODE_SINGLE_CLIENT:
- return "PROCESS_MODE_SINGLE_CLIENT";
- case PROCESS_MODE_MULTIPLE_CLIENTS:
- return "PROCESS_MODE_MULTIPLE_CLIENTS";
- case PROCESS_MODE_CONTINUOUS_RACK:
- return "PROCESS_MODE_CONTINUOUS_RACK";
- case PROCESS_MODE_PATCHBAY:
- return "PROCESS_MODE_PATCHBAY";
- }
-
- qWarning("CarlaBackend::ProcessModeType2Str(%i) - invalid type", mode);
- return nullptr;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-static inline
-const char* getPluginTypeString(const PluginType& type)
-{
- qDebug("CarlaBackend::getPluginTypeString(%s)", PluginType2Str(type));
-
- switch (type)
- {
- case PLUGIN_NONE:
- return "NONE";
- case PLUGIN_INTERNAL:
- return "INTERNAL";
- case PLUGIN_LADSPA:
- return "LADSPA";
- case PLUGIN_DSSI:
- return "DSSI";
- case PLUGIN_LV2:
- return "LV2";
- case PLUGIN_VST:
- return "VST";
- case PLUGIN_GIG:
- return "GIG";
- case PLUGIN_SF2:
- return "SF2";
- case PLUGIN_SFZ:
- return "SFZ";
- }
-
- return "NONE";
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-
-static inline
-uintptr_t getAddressFromPointer(void* const ptr)
-{
- qDebug("CarlaBackend::getAddressFromPointer(%p)", ptr);
- CARLA_ASSERT(ptr != nullptr);
-
- uintptr_t* addr = (uintptr_t*)&ptr;
- return *addr;
-}
-
-static inline
-void* getPointerFromAddress(const uintptr_t& addr)
-{
- CARLA_ASSERT(addr != 0);
-
- uintptr_t** const ptr = (uintptr_t**)&addr;
- return *ptr;
-}
-
-static inline
-PluginCategory getPluginCategoryFromName(const char* const name)
-{
- qDebug("CarlaBackend::getPluginCategoryFromName(\"%s\")", name);
- CARLA_ASSERT(name);
-
- if (! name)
- return PLUGIN_CATEGORY_NONE;
-
- CarlaString sname(name);
-
- if (sname.isEmpty())
- return PLUGIN_CATEGORY_NONE;
-
- sname.toLower();
-
- // generic tags first
- if (sname.contains("delay"))
- return PLUGIN_CATEGORY_DELAY;
- if (sname.contains("reverb"))
- return PLUGIN_CATEGORY_DELAY;
-
- // filter
- if (sname.contains("filter"))
- return PLUGIN_CATEGORY_FILTER;
-
- // dynamics
- if (sname.contains("dynamics"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("amplifier"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("compressor"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("enhancer"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("exciter"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("gate"))
- return PLUGIN_CATEGORY_DYNAMICS;
- if (sname.contains("limiter"))
- return PLUGIN_CATEGORY_DYNAMICS;
-
- // modulator
- if (sname.contains("modulator"))
- return PLUGIN_CATEGORY_MODULATOR;
- if (sname.contains("chorus"))
- return PLUGIN_CATEGORY_MODULATOR;
- if (sname.contains("flanger"))
- return PLUGIN_CATEGORY_MODULATOR;
- if (sname.contains("phaser"))
- return PLUGIN_CATEGORY_MODULATOR;
- if (sname.contains("saturator"))
- return PLUGIN_CATEGORY_MODULATOR;
-
- // utility
- if (sname.contains("utility"))
- return PLUGIN_CATEGORY_UTILITY;
- if (sname.contains("analyzer"))
- return PLUGIN_CATEGORY_UTILITY;
- if (sname.contains("converter"))
- return PLUGIN_CATEGORY_UTILITY;
- if (sname.contains("deesser"))
- return PLUGIN_CATEGORY_UTILITY;
- if (sname.contains("mixer"))
- return PLUGIN_CATEGORY_UTILITY;
-
- // common tags
- if (sname.contains("verb"))
- return PLUGIN_CATEGORY_DELAY;
-
- if (sname.contains("eq"))
- return PLUGIN_CATEGORY_EQ;
-
- if (sname.contains("tool"))
- return PLUGIN_CATEGORY_UTILITY;
-
- return PLUGIN_CATEGORY_NONE;
-}
-
-/**@}*/
-
-CARLA_BACKEND_END_NAMESPACE
-
-#endif // CARLA_BACKEND_UTILS_HPP
diff --git a/c++/carla-bridge/Makefile b/c++/carla-bridge/Makefile
deleted file mode 100644
index 309eb41..0000000
--- a/c++/carla-bridge/Makefile
+++ /dev/null
@@ -1,480 +0,0 @@
-#!/usr/bin/make -f
-# Makefile for carla-bridges #
-# ---------------------------------------- #
-# Created by falkTX
-#
-
-include ../Makefile.mk
-
-HAVE_GTK2 = $(shell pkg-config --exists gtk+-2.0 && echo true)
-HAVE_GTK3 = $(shell pkg-config --exists gtk+-3.0 && echo true)
-
-# --------------------------------------------------------------
-
-BUILD_CXX_FLAGS += -DBUILD_BRIDGE
-BUILD_CXX_FLAGS += -I. -I../carla-includes -I../carla-utils
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore QtXml)
-LINK_FLAGS += $(shell pkg-config --libs liblo QtCore QtXml)
-
-ifeq ($(CARLA_PLUGIN_SUPPORT),true)
-BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST
-endif
-
-ifeq ($(HAVE_QT5),true)
-QT_UI_FLAGS = $(shell pkg-config --cflags QtWidgets)
-QT_UI_LIBS = $(shell pkg-config --libs QtWidgets)
-else
-QT_UI_FLAGS = $(shell pkg-config --cflags QtGui)
-QT_UI_LIBS = $(shell pkg-config --libs QtGui)
-endif
-
-# --------------------------------------------------------------
-# Plugin bridges
-
-BUILD_PLUGIN_FLAGS = $(BUILD_CXX_FLAGS) -DBUILD_BRIDGE_PLUGIN -DBRIDGE_PLUGIN
-BUILD_PLUGIN_FLAGS += -DCARLA_ENGINE_JACK -I../carla-backend -I../carla-engine -I../carla-jackbridge -I../carla-plugin
-BUILD_PLUGIN_FLAGS += $(shell pkg-config --cflags jack) $(QT_UI_FLAGS)
-
-LINK_PLUGIN_FLAGS = $(LINK_FLAGS)
-LINK_PLUGIN_FLAGS += $(QT_UI_LIBS)
-
-POSIX_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS)
-POSIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu
-POSIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu
-POSIX_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) $(shell pkg-config --libs jack) -ldl
-
-WIN_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS) -DJACKBRIDGE_EXPORT -DPTW32_STATIC_LIB
-WIN_32BIT_FLAGS = $(32BIT_FLAGS)
-WIN_64BIT_FLAGS = $(64BIT_FLAGS)
-WIN_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) -mwindows -L../carla-jackbridge -lpthread -lwinspool -lole32 -luuid -limm32 -lshell32 -lws2_32
-
-# --------------------------------------------------------------
-# UI bridges
-
-BUILD_UI_FLAGS = $(BUILD_CXX_FLAGS) -DBUILD_BRIDGE_UI
-LINK_UI_FLAGS = $(LINK_FLAGS) -ldl
-
-BUILD_UI_LV2_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_LV2
-BUILD_UI_VST_FLAGS = $(BUILD_UI_FLAGS) -DBRIDGE_VST
-
-BUILD_UI_LV2_GTK2_FLAGS = $(BUILD_UI_LV2_FLAGS) -DBRIDGE_GTK2 -DBRIDGE_LV2_GTK2 $(shell pkg-config --cflags gtk+-2.0)
-LINK_UI_LV2_GTK2_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs gtk+-2.0)
-
-BUILD_UI_LV2_GTK3_FLAGS = $(BUILD_UI_LV2_FLAGS) -DBRIDGE_GTK3 -DBRIDGE_LV2_GTK3 $(shell pkg-config --cflags gtk+-3.0)
-LINK_UI_LV2_GTK3_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs gtk+-3.0)
-
-BUILD_UI_LV2_QT4_FLAGS = $(BUILD_UI_LV2_FLAGS) -DBRIDGE_QT4 -DBRIDGE_LV2_QT4 $(shell pkg-config --cflags QtGui)
-LINK_UI_LV2_QT4_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs QtGui)
-
-BUILD_UI_LV2_QT5_FLAGS = $(BUILD_UI_LV2_FLAGS) -DBRIDGE_QT5 -DBRIDGE_LV2_QT5 $(shell pkg-config --cflags QtWidgets)
-LINK_UI_LV2_QT5_FLAGS = $(LINK_UI_FLAGS) $(shell pkg-config --libs QtWidgets)
-
-BUILD_UI_LV2_HWND_FLAGS = $(BUILD_UI_VST_FLAGS) -DBRIDGE_HWND -DBRIDGE_LV2_HWND $(QT_UI_FLAGS)
-LINK_UI_LV2_HWND_FLAGS = $(LINK_FLAGS) $(QT_UI_LIBS) -mwindows -static
-
-BUILD_UI_LV2_X11_FLAGS = $(BUILD_UI_LV2_FLAGS) -DBRIDGE_X11 -DBRIDGE_LV2_X11 $(QT_UI_FLAGS)
-LINK_UI_LV2_X11_FLAGS = $(LINK_UI_FLAGS) $(QT_UI_LIBS)
-
-BUILD_UI_VST_HWND_FLAGS = $(BUILD_UI_VST_FLAGS) -DBRIDGE_HWND -DBRIDGE_VST_HWND $(QT_UI_FLAGS)
-LINK_UI_VST_HWND_FLAGS = $(LINK_FLAGS) $(QT_UI_LIBS) -mwindows -static
-
-BUILD_UI_VST_X11_FLAGS = $(BUILD_UI_VST_FLAGS) -DBRIDGE_X11 -DBRIDGE_VST_X11 $(QT_UI_FLAGS)
-LINK_UI_VST_X11_FLAGS = $(LINK_UI_FLAGS) $(QT_UI_LIBS)
-
-# --------------------------------------------------------------
-
-ifeq ($(CARLA_PLUGIN_SUPPORT),true)
-all: native ui_lv2-gtk2 ui_lv2-gtk3 ui_lv2-qt4 ui_lv2-qt5 ui_lv2-x11 ui_vst-x11
-
-ifeq ($(HAVE_GTK2),true)
-ui_lv2-gtk2: carla-bridge-lv2-gtk2
-else
-ui_lv2-gtk2:
-endif
-
-ifeq ($(HAVE_GTK3),true)
-ui_lv2-gtk3: carla-bridge-lv2-gtk3
-else
-ui_lv2-gtk3:
-endif
-
-ifneq ($(HAVE_QT5),true)
-ui_lv2-qt4: carla-bridge-lv2-qt4
-ui_lv2-qt5:
-else
-ui_lv2-qt4:
-ui_lv2-qt5: carla-bridge-lv2-qt5
-endif
-
-ui_lv2-hwnd: carla-bridge-lv2-hwnd.exe
-ui_lv2-x11: carla-bridge-lv2-x11
-
-ui_vst-hwnd: carla-bridge-vst-hwnd.exe
-ui_vst-x11: carla-bridge-vst-x11
-
-else # CARLA_PLUGIN_SUPPORT
-all:
-endif
-
-# --------------------------------------------------------------
-
-native: carla-bridge-native
-posix32: carla-bridge-posix32
-posix64: carla-bridge-posix64
-win32: carla-bridge-win32.exe
-win64: carla-bridge-win64.exe
-
-# --------------------------------------------------------------
-# UI common
-
-%__lv2.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_FLAGS) -c -o $@
-
-%__vst.o: %.cpp
- $(CXX) $< $(BUILD_UI_VST_FLAGS) -c -o $@
-
-OBJS_UI_LV2_LIBS = \
- ../carla-lilv/carla_lilv.a \
- ../carla-rtmempool/carla_rtmempool.a
-
-# --------------------------------------------------------------
-# ui_lv2-gtk2
-
-OBJS_UI_LV2_GTK2 = carla_bridge_ui-lv2__lv2-gtk2.o \
- carla_bridge_client__lv2.o carla_bridge_osc__lv2.o \
- carla_bridge_toolkit__lv2.o carla_bridge_toolkit-gtk__lv2-gtk2.o
-
-carla-bridge-lv2-gtk2: $(OBJS_UI_LV2_GTK2) $(OBJS_UI_LV2_LIBS)
- $(CXX) $^ $(LINK_UI_LV2_GTK2_FLAGS) -o $@ && $(STRIP) $@
-
-%__lv2-gtk2.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_GTK2_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_lv2-gtk3
-
-OBJS_UI_LV2_GTK3 = carla_bridge_ui-lv2__lv2-gtk3.o \
- carla_bridge_client__lv2.o carla_bridge_osc__lv2.o \
- carla_bridge_toolkit__lv2.o carla_bridge_toolkit-gtk__lv2-gtk3.o
-
-carla-bridge-lv2-gtk3: $(OBJS_UI_LV2_GTK3) $(OBJS_UI_LV2_LIBS)
- $(CXX) $^ $(LINK_UI_LV2_GTK3_FLAGS) -o $@ && $(STRIP) $@
-
-%__lv2-gtk3.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_GTK3_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_lv2-qt4
-
-OBJS_UI_LV2_QT4 = carla_bridge_ui-lv2__lv2-qt4.o \
- carla_bridge_client__lv2.o carla_bridge_osc__lv2.o \
- carla_bridge_toolkit__lv2.o carla_bridge_toolkit-qt__lv2-qt4.o
-
-carla-bridge-lv2-qt4: $(OBJS_UI_LV2_QT4) $(OBJS_UI_LV2_LIBS)
- $(CXX) $^ $(LINK_UI_LV2_QT4_FLAGS) -o $@ && $(STRIP) $@
-
-%__lv2-qt4.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_QT4_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_lv2-qt5
-
-OBJS_UI_LV2_QT5 = carla_bridge_ui-lv2__lv2-qt5.o \
- carla_bridge_client__lv2.o carla_bridge_osc__lv2.o \
- carla_bridge_toolkit__lv2.o carla_bridge_toolkit-qt__lv2-qt5.o
-
-carla-bridge-lv2-qt5: $(OBJS_UI_LV2_QT5) $(OBJS_UI_LV2_LIBS)
- $(CXX) $^ $(LINK_UI_LV2_QT5_FLAGS) -o $@ && $(STRIP) $@
-
-%__lv2-qt5.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_QT5_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_lv2-x11
-
-OBJS_UI_LV2_X11 = carla_bridge_ui-lv2__lv2-x11.o \
- carla_bridge_client__lv2.o carla_bridge_osc__lv2.o \
- carla_bridge_toolkit__lv2.o carla_bridge_toolkit-qt__lv2-x11.o
-
-carla-bridge-lv2-x11: $(OBJS_UI_LV2_X11) $(OBJS_UI_LV2_LIBS)
- $(CXX) $^ $(LINK_UI_LV2_X11_FLAGS) -o $@ && $(STRIP) $@
-
-%__lv2-x11.o: %.cpp
- $(CXX) $< $(BUILD_UI_LV2_X11_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_vst-hwnd
-
-OBJS_UI_VST_HWND = carla_bridge_ui-vst__vst-hwnd.o \
- carla_bridge_client__vst.o carla_bridge_osc__vst.o \
- carla_bridge_toolkit__vst.o carla_bridge_toolkit-qt__vst-hwnd.o
-
-carla-bridge-vst-hwnd.exe: $(OBJS_UI_VST_HWND)
- $(CXX) $^ $(LINK_UI_VST_HWND_FLAGS) -o $@ && $(STRIP) $@
-
-%__vst-hwnd.o: %.cpp
- $(CXX) $< $(BUILD_UI_VST_HWND_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# ui_vst-x11
-
-OBJS_UI_VST_X11 = carla_bridge_ui-vst__vst-x11.o \
- carla_bridge_client__vst.o carla_bridge_osc__vst.o \
- carla_bridge_toolkit__vst.o carla_bridge_toolkit-qt__vst-x11.o
-
-carla-bridge-vst-x11: $(OBJS_UI_VST_X11)
- $(CXX) $^ $(LINK_UI_VST_X11_FLAGS) -o $@ && $(STRIP) $@
-
-%__vst-x11.o: %.cpp
- $(CXX) $< $(BUILD_UI_VST_X11_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# native
-
-NATIVE_BUILD_FLAGS = $(BUILD_PLUGIN_FLAGS)
-NATIVE_LINK_FLAGS = $(LINK_PLUGIN_FLAGS) $(shell pkg-config --libs jack) -ldl
-
-ifeq ($(HAVE_SUIL),true)
-NATIVE_BUILD_FLAGS += $(shell pkg-config --cflags suil-0) -DWANT_SUIL
-NATIVE_LINK_FLAGS += $(shell pkg-config --libs suil-0)
-endif
-
-OBJS_NATIVE = carla_bridge_plugin__native.o \
- carla_bridge_client__native.o carla_bridge_osc__native.o \
- carla_bridge_toolkit__native.o
-
-# carla
-OBJS_NATIVE += \
- ../carla/Shared__native.o
-
-# carla-engine
-OBJS_NATIVE += \
- ../carla-engine/carla_engine__native.o \
- ../carla-engine/carla_engine_osc__native.o \
- ../carla-engine/carla_engine_thread__native.o \
- ../carla-engine/jack__native.o
-
-# carla-plugin
-OBJS_NATIVE += \
- ../carla-plugin/carla_plugin__native.o \
- ../carla-plugin/carla_plugin_thread__native.o \
- ../carla-plugin/ladspa__native.o \
- ../carla-plugin/dssi__native.o \
- ../carla-plugin/lv2__native.o \
- ../carla-plugin/vst__native.o
-
-# libs
-OBJS_NATIVE += \
- ../carla-lilv/carla_lilv.a \
- ../carla-rtmempool/carla_rtmempool.a
-
-carla-bridge-native: $(OBJS_NATIVE)
- $(CXX) $^ $(NATIVE_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-%__native.o: %.cpp
- $(CXX) $< $(NATIVE_BUILD_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# posix32
-
-OBJS_POSIX32 = carla_bridge_plugin__posix32.o \
- carla_bridge_client__posix32.o carla_bridge_osc__posix32.o \
- carla_bridge_toolkit__posix32.o
-
-# carla
-OBJS_POSIX32 += \
- ../carla/Shared__posix32.o
-
-# carla-engine
-OBJS_POSIX32 += \
- ../carla-engine/carla_engine__posix32.o \
- ../carla-engine/carla_engine_osc__posix32.o \
- ../carla-engine/carla_engine_thread__posix32.o \
- ../carla-engine/jack__posix32.o
-
-# carla-plugin
-OBJS_POSIX32 += \
- ../carla-plugin/carla_plugin__posix32.o \
- ../carla-plugin/carla_plugin_thread__posix32.o \
- ../carla-plugin/ladspa__posix32.o \
- ../carla-plugin/dssi__posix32.o \
- ../carla-plugin/lv2__posix32.o \
- ../carla-plugin/vst__posix32.o
-
-# libs
-OBJS_POSIX32 += \
- ../carla-lilv/carla_lilv_posix32.a \
- ../carla-rtmempool/carla_rtmempool_posix32.a
-
-carla-bridge-posix32: $(OBJS_POSIX32)
- $(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_32BIT_FLAGS) -o $@ && $(STRIP) $@
-
-%__posix32.o: %.cpp
- $(CXX) $< $(POSIX_BUILD_FLAGS) $(POSIX_32BIT_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# posix64
-
-OBJS_POSIX64 = carla_bridge_plugin__posix64.o \
- carla_bridge_client__posix64.o carla_bridge_osc__posix64.o \
- carla_bridge_toolkit__posix64.o
-
-# carla
-OBJS_POSIX64 += \
- ../carla/Shared__posix64.o
-
-# carla-engine
-OBJS_POSIX64 += \
- ../carla-engine/carla_engine__posix64.o \
- ../carla-engine/carla_engine_osc__posix64.o \
- ../carla-engine/carla_engine_thread__posix64.o \
- ../carla-engine/jack__posix64.o
-
-# carla-plugin
-OBJS_POSIX64 += \
- ../carla-plugin/carla_plugin__posix64.o \
- ../carla-plugin/carla_plugin_thread__posix64.o \
- ../carla-plugin/ladspa__posix64.o \
- ../carla-plugin/dssi__posix64.o \
- ../carla-plugin/lv2__posix64.o \
- ../carla-plugin/vst__posix64.o
-
-# libs
-OBJS_POSIX64 += \
- ../carla-lilv/carla_lilv_posix64.a \
- ../carla-rtmempool/carla_rtmempool_posix64.a
-
-carla-bridge-posix64: $(OBJS_POSIX64)
- $(CXX) $^ $(POSIX_LINK_FLAGS) $(POSIX_64BIT_FLAGS) -o $@ && $(STRIP) $@
-
-%__posix64.o: %.cpp
- $(CXX) $< $(POSIX_BUILD_FLAGS) $(POSIX_64BIT_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# win32
-
-OBJS_WIN32 = carla_bridge_plugin__win32.o \
- carla_bridge_client__win32.o carla_bridge_osc__win32.o \
- carla_bridge_toolkit__win32.o
-
-# carla
-OBJS_WIN32 += \
- ../carla/Shared__win32.o
-
-# carla-engine
-OBJS_WIN32 += \
- ../carla-engine/carla_engine__win32.o \
- ../carla-engine/carla_engine_osc__win32.o \
- ../carla-engine/carla_engine_thread__win32.o \
- ../carla-engine/jack__win32.o
-
-# carla-plugin
-OBJS_WIN32 += \
- ../carla-plugin/carla_plugin__win32.o \
- ../carla-plugin/carla_plugin_thread__win32.o \
- ../carla-plugin/ladspa__win32.o \
- ../carla-plugin/dssi__win32.o \
- ../carla-plugin/lv2__win32.o \
- ../carla-plugin/vst__win32.o
-
-# libs
-OBJS_WIN32 += \
- ../carla-lilv/carla_lilv_win32.a \
- ../carla-rtmempool/carla_rtmempool_win32.a
-
-carla-bridge-win32.exe: $(OBJS_WIN32) ../carla-jackbridge/libcarla-jackbridge-win32.dll
- $(CXX) $(OBJS_WIN32) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -lcarla-jackbridge-win32 -o $@ && $(STRIP) $@
-
-%__win32.o: %.cpp
- $(CXX) $< $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-# win64
-
-OBJS_WIN64 = carla_bridge_plugin__win64.o \
- carla_bridge_client__win64.o carla_bridge_osc__win64.o \
- carla_bridge_toolkit__win64.o
-
-# carla
-OBJS_WIN64 += \
- ../carla/Shared__win64.o
-
-# carla-engine
-OBJS_WIN64 += \
- ../carla-engine/carla_engine__win64.o \
- ../carla-engine/carla_engine_osc__win64.o \
- ../carla-engine/carla_engine_thread__win64.o \
- ../carla-engine/jack__win64.o
-
-# carla-plugin
-OBJS_WIN64 += \
- ../carla-plugin/carla_plugin__win64.o \
- ../carla-plugin/carla_plugin_thread__win64.o \
- ../carla-plugin/ladspa__win64.o \
- ../carla-plugin/dssi__win64.o \
- ../carla-plugin/lv2__win64.o \
- ../carla-plugin/vst__win64.o
-
-# libs
-OBJS_WIN64 += \
- ../carla-lilv/carla_lilv_win64.a \
- ../carla-rtmempool/carla_rtmempool_win64.a
-
-carla-bridge-win64.exe: $(OBJS_WIN64) ../carla-jackbridge/libcarla-jackbridge-win64.dll
- $(CXX) $(OBJS_WIN64) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -lcarla-jackbridge-win64 -o $@ && $(STRIP) $@
-
-%__win64.o: %.cpp
- $(CXX) $< $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) -c -o $@
-
-# --------------------------------------------------------------
-
-../carla-lilv/carla_lilv.a:
- $(MAKE) -C ../carla-lilv
-
-../carla-lilv/carla_lilv_posix32.a:
- $(MAKE) -C ../carla-lilv posix32
-
-../carla-lilv/carla_lilv_posix64.a:
- $(MAKE) -C ../carla-lilv posix64
-
-../carla-lilv/carla_lilv_win32.a:
- $(MAKE) -C ../carla-lilv win32
-
-../carla-lilv/carla_lilv_win64.a:
- $(MAKE) -C ../carla-lilv win64
-
-../carla-rtmempool/carla_rtmempool.a:
- $(MAKE) -C ../carla-rtmempool
-
-../carla-rtmempool/carla_rtmempool_posix32.a:
- $(MAKE) -C ../carla-rtmempool posix32
-
-../carla-rtmempool/carla_rtmempool_posix64.a:
- $(MAKE) -C ../carla-rtmempool posix64
-
-../carla-rtmempool/carla_rtmempool_win32.a:
- $(MAKE) -C ../carla-rtmempool win32
-
-../carla-rtmempool/carla_rtmempool_win64.a:
- $(MAKE) -C ../carla-rtmempool win64
-
-../carla-jackbridge/libcarla-jackbridge-win32.dll:
- $(MAKE) -C ../carla-jackbridge win32
-
-../carla-jackbridge/libcarla-jackbridge-win64.dll:
- $(MAKE) -C ../carla-jackbridge win64
-
-# --------------------------------------------------------------
-
-doxygen: carla_bridge.doxygen
- doxygen $<
-
-clean:
- rm -f *.o *.dll *.so *.exe
- rm -f $(OBJS_NATIVE)
- rm -f $(OBJS_POSIX32)
- rm -f $(OBJS_POSIX64)
- rm -f $(OBJS_WIN32)
- rm -f $(OBJS_WIN64)
- rm -f carla-bridge-lv2-gtk2 carla-bridge-lv2-gtk3 carla-bridge-lv2-qt4 carla-bridge-lv2-qt5 carla-bridge-lv2-x11 carla-bridge-vst-x11
- rm -f carla-bridge-native carla-bridge-posix32 carla-bridge-posix64
diff --git a/c++/carla-bridge/carla_bridge.doxygen b/c++/carla-bridge/carla_bridge.doxygen
deleted file mode 100644
index 4dd7dc1..0000000
--- a/c++/carla-bridge/carla_bridge.doxygen
+++ /dev/null
@@ -1,287 +0,0 @@
-# Doxyfile 1.7.6.1
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-DOXYFILE_ENCODING = UTF-8
-PROJECT_NAME = "Carla Bridge"
-PROJECT_NUMBER =
-PROJECT_BRIEF =
-PROJECT_LOGO =
-OUTPUT_DIRECTORY = ../../doc/carla-bridge
-CREATE_SUBDIRS = NO
-OUTPUT_LANGUAGE = English
-BRIEF_MEMBER_DESC = YES
-REPEAT_BRIEF = YES
-ABBREVIATE_BRIEF =
-ALWAYS_DETAILED_SEC = NO
-INLINE_INHERITED_MEMB = NO
-FULL_PATH_NAMES = YES
-STRIP_FROM_PATH =
-STRIP_FROM_INC_PATH =
-SHORT_NAMES = NO
-JAVADOC_AUTOBRIEF = NO
-QT_AUTOBRIEF = NO
-MULTILINE_CPP_IS_BRIEF = NO
-INHERIT_DOCS = YES
-SEPARATE_MEMBER_PAGES = NO
-TAB_SIZE = 4
-ALIASES =
-TCL_SUBST =
-OPTIMIZE_OUTPUT_FOR_C = NO
-OPTIMIZE_OUTPUT_JAVA = NO
-OPTIMIZE_FOR_FORTRAN = NO
-OPTIMIZE_OUTPUT_VHDL = NO
-EXTENSION_MAPPING =
-BUILTIN_STL_SUPPORT = NO
-CPP_CLI_SUPPORT = NO
-SIP_SUPPORT = NO
-IDL_PROPERTY_SUPPORT = YES
-DISTRIBUTE_GROUP_DOC = NO
-SUBGROUPING = YES
-INLINE_GROUPED_CLASSES = NO
-INLINE_SIMPLE_STRUCTS = NO
-TYPEDEF_HIDES_STRUCT = NO
-SYMBOL_CACHE_SIZE = 0
-LOOKUP_CACHE_SIZE = 0
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-EXTRACT_ALL = YES
-EXTRACT_PRIVATE = NO
-EXTRACT_STATIC = NO
-EXTRACT_LOCAL_CLASSES = YES
-EXTRACT_LOCAL_METHODS = NO
-EXTRACT_ANON_NSPACES = NO
-HIDE_UNDOC_MEMBERS = NO
-HIDE_UNDOC_CLASSES = NO
-HIDE_FRIEND_COMPOUNDS = NO
-HIDE_IN_BODY_DOCS = NO
-INTERNAL_DOCS = NO
-CASE_SENSE_NAMES = YES
-HIDE_SCOPE_NAMES = NO
-SHOW_INCLUDE_FILES = YES
-FORCE_LOCAL_INCLUDES = NO
-INLINE_INFO = YES
-SORT_MEMBER_DOCS = NO
-SORT_BRIEF_DOCS = NO
-SORT_MEMBERS_CTORS_1ST = NO
-SORT_GROUP_NAMES = NO
-SORT_BY_SCOPE_NAME = NO
-STRICT_PROTO_MATCHING = NO
-GENERATE_TODOLIST = YES
-GENERATE_TESTLIST = YES
-GENERATE_BUGLIST = YES
-GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS =
-MAX_INITIALIZER_LINES = 30
-SHOW_USED_FILES = YES
-SHOW_DIRECTORIES = NO
-SHOW_FILES = YES
-SHOW_NAMESPACES = YES
-FILE_VERSION_FILTER =
-LAYOUT_FILE =
-CITE_BIB_FILES =
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-QUIET = NO
-WARNINGS = YES
-WARN_IF_UNDOCUMENTED = YES
-WARN_IF_DOC_ERROR = YES
-WARN_NO_PARAMDOC = NO
-WARN_FORMAT = "$file:$line: $text"
-WARN_LOGFILE =
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT =
-INPUT_ENCODING = UTF-8
-FILE_PATTERNS =
-RECURSIVE = NO
-EXCLUDE = carla_bridge_osc.hpp carla_bridge_osc.cpp carla_bridge_plugin.cpp
-EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS =
-EXCLUDE_SYMBOLS =
-EXAMPLE_PATH =
-EXAMPLE_PATTERNS =
-EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
-FILTER_SOURCE_FILES = NO
-FILTER_SOURCE_PATTERNS =
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-SOURCE_BROWSER = NO
-INLINE_SOURCES = NO
-STRIP_CODE_COMMENTS = YES
-REFERENCED_BY_RELATION = NO
-REFERENCES_RELATION = NO
-REFERENCES_LINK_SOURCE = YES
-USE_HTAGS = NO
-VERBATIM_HEADERS = YES
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-ALPHABETICAL_INDEX = YES
-COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-GENERATE_HTML = YES
-HTML_OUTPUT = .
-HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
-HTML_EXTRA_FILES =
-HTML_COLORSTYLE_HUE = 220
-HTML_COLORSTYLE_SAT = 100
-HTML_COLORSTYLE_GAMMA = 80
-HTML_TIMESTAMP = YES
-HTML_ALIGN_MEMBERS = YES
-HTML_DYNAMIC_SECTIONS = NO
-GENERATE_DOCSET = NO
-DOCSET_FEEDNAME = "Doxygen generated docs"
-DOCSET_BUNDLE_ID = org.doxygen.Project
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-DOCSET_PUBLISHER_NAME = Publisher
-GENERATE_HTMLHELP = NO
-CHM_FILE =
-HHC_LOCATION =
-GENERATE_CHI = NO
-CHM_INDEX_ENCODING =
-BINARY_TOC = NO
-TOC_EXPAND = NO
-GENERATE_QHP = NO
-QCH_FILE =
-QHP_NAMESPACE = org.doxygen.Project
-QHP_VIRTUAL_FOLDER = doc
-QHP_CUST_FILTER_NAME =
-QHP_CUST_FILTER_ATTRS =
-QHP_SECT_FILTER_ATTRS =
-QHG_LOCATION =
-GENERATE_ECLIPSEHELP = NO
-ECLIPSE_DOC_ID = org.doxygen.Project
-DISABLE_INDEX = NO
-GENERATE_TREEVIEW = NO
-ENUM_VALUES_PER_LINE = 4
-USE_INLINE_TREES = NO
-TREEVIEW_WIDTH = 250
-EXT_LINKS_IN_WINDOW = NO
-FORMULA_FONTSIZE = 10
-FORMULA_TRANSPARENT = YES
-USE_MATHJAX = NO
-MATHJAX_RELPATH = http://www.mathjax.org/mathjax
-MATHJAX_EXTENSIONS =
-SEARCHENGINE = YES
-SERVER_BASED_SEARCH = NO
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-GENERATE_LATEX = NO
-LATEX_OUTPUT = latex
-LATEX_CMD_NAME = latex
-MAKEINDEX_CMD_NAME = makeindex
-COMPACT_LATEX = NO
-PAPER_TYPE = a4
-EXTRA_PACKAGES =
-LATEX_HEADER =
-LATEX_FOOTER =
-PDF_HYPERLINKS = YES
-USE_PDFLATEX = YES
-LATEX_BATCHMODE = NO
-LATEX_HIDE_INDICES = NO
-LATEX_SOURCE_CODE = NO
-LATEX_BIB_STYLE = plain
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-GENERATE_RTF = NO
-RTF_OUTPUT = rtf
-COMPACT_RTF = NO
-RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-GENERATE_MAN = NO
-MAN_OUTPUT = man
-MAN_EXTENSION = .3
-MAN_LINKS = NO
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-GENERATE_XML = NO
-XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
-XML_PROGRAMLISTING = YES
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-GENERATE_AUTOGEN_DEF = NO
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-GENERATE_PERLMOD = NO
-PERLMOD_LATEX = NO
-PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-ENABLE_PREPROCESSING = YES
-MACRO_EXPANSION = NO
-EXPAND_ONLY_PREDEF = NO
-SEARCH_INCLUDES = YES
-INCLUDE_PATH =
-INCLUDE_FILE_PATTERNS =
-PREDEFINED = DOXYGEN BUILD_BRIDGE BUILD_BRIDGE_PLUGIN BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_LV2_GTK2 BRIDGE_LV2_GTK3 BRIDGE_LV2_QT4 BRIDGE_LV2_X11 BRIDGE_VST BRIDGE_VST_HWND BRIDGE_VST_X11
-EXPAND_AS_DEFINED =
-SKIP_FUNCTION_MACROS = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-TAGFILES =
-GENERATE_TAGFILE =
-ALLEXTERNALS = NO
-EXTERNAL_GROUPS = YES
-PERL_PATH = /usr/bin/perl
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-CLASS_DIAGRAMS = YES
-MSCGEN_PATH =
-HIDE_UNDOC_RELATIONS = YES
-HAVE_DOT = NO
-DOT_NUM_THREADS = 0
-DOT_FONTNAME = Helvetica
-DOT_FONTSIZE = 10
-DOT_FONTPATH =
-CLASS_GRAPH = YES
-COLLABORATION_GRAPH = YES
-GROUP_GRAPHS = YES
-UML_LOOK = NO
-TEMPLATE_RELATIONS = NO
-INCLUDE_GRAPH = YES
-INCLUDED_BY_GRAPH = YES
-CALL_GRAPH = NO
-CALLER_GRAPH = NO
-GRAPHICAL_HIERARCHY = YES
-DIRECTORY_GRAPH = YES
-DOT_IMAGE_FORMAT = png
-INTERACTIVE_SVG = NO
-DOT_PATH =
-DOTFILE_DIRS =
-MSCFILE_DIRS =
-DOT_GRAPH_MAX_NODES = 50
-MAX_DOT_GRAPH_DEPTH = 0
-DOT_TRANSPARENT = NO
-DOT_MULTI_TARGETS = YES
-GENERATE_LEGEND = YES
-DOT_CLEANUP = YES
diff --git a/c++/carla-bridge/carla_bridge.hpp b/c++/carla-bridge/carla_bridge.hpp
deleted file mode 100644
index 960126a..0000000
--- a/c++/carla-bridge/carla_bridge.hpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Carla Bridge
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BRIDGE_HPP
-#define CARLA_BRIDGE_HPP
-
-#include "carla_defines.hpp"
-
-#define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge {
-#define CARLA_BRIDGE_END_NAMESPACE }
-#define CARLA_BRIDGE_USE_NAMESPACE using namespace CarlaBridge;
-
-CARLA_BRIDGE_START_NAMESPACE
-
-class CarlaBridgeClient;
-class CarlaBridgeToolkit;
-
-CARLA_BRIDGE_END_NAMESPACE
-
-#endif // CARLA_BRIDGE_HPP
diff --git a/c++/carla-bridge/carla_bridge_client.cpp b/c++/carla-bridge/carla_bridge_client.cpp
deleted file mode 100644
index 5131689..0000000
--- a/c++/carla-bridge/carla_bridge_client.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Carla Bridge Client
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_bridge_client.hpp"
-#include "carla_bridge_toolkit.hpp"
-
-#ifdef BUILD_BRIDGE_UI
-# include "carla_lib_utils.hpp"
-#endif
-
-#include
-#include
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// ---------------------------------------------------------------------
-
-CarlaBridgeClient::CarlaBridgeClient(const char* const uiTitle)
- : m_osc(this),
- m_toolkit(CarlaBridgeToolkit::createNew(this, uiTitle))
-{
- qDebug("CarlaBridgeClient::CarlaBridgeClient(\"%s\")", uiTitle);
-
- m_oscData = nullptr;
-
-#ifdef BUILD_BRIDGE_UI
- m_uiFilename = nullptr;
- m_uiLib = nullptr;
- m_uiQuit = false;
-#endif
-}
-
-CarlaBridgeClient::~CarlaBridgeClient()
-{
- qDebug("CarlaBridgeClient::~CarlaBridgeClient()");
-
-#ifdef BUILD_BRIDGE_UI
- if (m_uiFilename)
- free(m_uiFilename);
-#endif
-
- delete m_toolkit;
-}
-
-#ifdef BUILD_BRIDGE_UI
-// ---------------------------------------------------------------------
-// ui initialization
-
-bool CarlaBridgeClient::init(const char* const, const char* const)
-{
- qDebug("CarlaBridgeClient::init()");
-
- // Test for single init
- {
- static bool initiated = false;
- CARLA_ASSERT(! initiated);
- initiated = true;
- }
-
- m_uiQuit = false;
-
- m_toolkit->init();
-
- return false;
-}
-
-void CarlaBridgeClient::close()
-{
- qDebug("CarlaBridgeClient::close()");
-
- if (! m_uiQuit)
- {
- m_uiQuit = true;
-
- if (isOscControlRegistered())
- sendOscExiting();
- }
-
- m_toolkit->quit();
-}
-#endif
-
-// ---------------------------------------------------------------------
-// osc stuff
-
-bool CarlaBridgeClient::oscInit(const char* const url)
-{
- qDebug("CarlaBridgeClient::oscInit(\"%s\")", url);
-
- const bool ret = m_osc.init(url);
- m_oscData = m_osc.getControlData();
-
- return ret;
-}
-
-bool CarlaBridgeClient::oscIdle()
-{
- m_osc.idle();
-
-#ifdef BUILD_BRIDGE_UI
- return ! m_uiQuit;
-#else
- return true;
-#endif
-}
-
-void CarlaBridgeClient::oscClose()
-{
- qDebug("CarlaBridgeClient::oscClose()");
- CARLA_ASSERT(m_oscData);
-
- m_osc.close();
- m_oscData = nullptr;
-}
-
-bool CarlaBridgeClient::isOscControlRegistered() const
-{
- return m_osc.isControlRegistered();
-}
-
-void CarlaBridgeClient::sendOscUpdate()
-{
- qDebug("CarlaBridgeClient::sendOscUpdate()");
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_update(m_oscData, m_osc.getServerPath());
-}
-
-#ifdef BUILD_BRIDGE_PLUGIN
-void CarlaBridgeClient::sendOscBridgeUpdate()
-{
- qDebug("CarlaBridgeClient::sendOscBridgeUpdate()");
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(m_oscData->target && m_oscData->path);
-
- if (m_oscData && m_oscData->target && m_oscData->path)
- osc_send_bridge_update(m_oscData, m_oscData->path);
-}
-
-void CarlaBridgeClient::sendOscBridgeError(const char* const error)
-{
- qDebug("CarlaBridgeClient::sendOscBridgeError(\"%s\")", error);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(error);
-
- if (m_oscData && m_oscData->target)
- osc_send_bridge_error(m_oscData, error);
-}
-#endif
-
-// ---------------------------------------------------------------------
-// toolkit
-
-void CarlaBridgeClient::toolkitShow()
-{
- qDebug("CarlaBridgeClient::toolkitShow()");
-
- m_toolkit->show();
-}
-
-void CarlaBridgeClient::toolkitHide()
-{
- qDebug("CarlaBridgeClient::toolkitHide()");
-
- m_toolkit->hide();
-}
-
-void CarlaBridgeClient::toolkitResize(const int width, const int height)
-{
- qDebug("CarlaBridgeClient::toolkitResize(%i, %i)", width, height);
-
- m_toolkit->resize(width, height);
-}
-
-void CarlaBridgeClient::toolkitExec(const bool showGui)
-{
- qDebug("CarlaBridgeClient::toolkitExec(%s)", bool2str(showGui));
-
- m_toolkit->exec(showGui);
-}
-
-void CarlaBridgeClient::toolkitQuit()
-{
- qDebug("CarlaBridgeClient::toolkitQuit()");
-
-#ifdef BUILD_BRIDGE_UI
- m_uiQuit = true;
-#endif
- m_toolkit->quit();
-}
-
-// ---------------------------------------------------------------------
-
-void CarlaBridgeClient::sendOscConfigure(const char* const key, const char* const value)
-{
- qDebug("CarlaBridgeClient::sendOscConfigure(\"%s\", \"%s\")", key, value);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_configure(m_oscData, key, value);
-}
-
-void CarlaBridgeClient::sendOscControl(const int32_t index, const float value)
-{
- qDebug("CarlaBridgeClient::sendOscControl(%i, %f)", index, value);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_control(m_oscData, index, value);
-}
-
-void CarlaBridgeClient::sendOscProgram(const int32_t index)
-{
- qDebug("CarlaBridgeClient::sendOscProgram(%i)", index);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_program(m_oscData, index);
-}
-
-void CarlaBridgeClient::sendOscMidiProgram(const int32_t index)
-{
- qDebug("CarlaBridgeClient::sendOscMidiProgram(%i)", index);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_midi_program(m_oscData, index);
-}
-
-void CarlaBridgeClient::sendOscMidi(const uint8_t midiBuf[4])
-{
- qDebug("CarlaBridgeClient::sendOscMidi(%p)", midiBuf);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_midi(m_oscData, midiBuf);
-}
-
-void CarlaBridgeClient::sendOscExiting()
-{
- qDebug("CarlaBridgeClient::sendOscExiting()");
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_exiting(m_oscData);
-}
-
-#ifdef BRIDGE_LV2
-void CarlaBridgeClient::sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
-{
- qDebug("CarlaBridgeClient::sendOscLv2TransferAtom(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_lv2_transfer_atom(m_oscData, portIndex, typeStr, atomBuf);
-}
-
-void CarlaBridgeClient::sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf)
-{
- qDebug("CarlaBridgeClient::sendOscLv2TransferEvent(%i, \"%s\", \"%s\")", portIndex, typeStr, atomBuf);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- osc_send_lv2_transfer_event(m_oscData, portIndex, typeStr, atomBuf);
-}
-#endif
-
-// ---------------------------------------------------------------------
-
-void* CarlaBridgeClient::getContainerId()
-{
- return m_toolkit->getContainerId();
-}
-
-#ifdef BUILD_BRIDGE_UI
-bool CarlaBridgeClient::uiLibOpen(const char* const filename)
-{
- CARLA_ASSERT(! m_uiLib);
- CARLA_ASSERT(filename);
-
- if (m_uiFilename)
- free(m_uiFilename);
-
- m_uiLib = lib_open(filename);
- m_uiFilename = strdup(filename ? filename : "");
-
- return bool(m_uiLib);
-}
-
-bool CarlaBridgeClient::uiLibClose()
-{
- CARLA_ASSERT(m_uiLib);
-
- if (m_uiLib)
- {
- const bool closed = lib_close(m_uiLib);
- m_uiLib = nullptr;
- return closed;
- }
-
- return false;
-}
-
-void* CarlaBridgeClient::uiLibSymbol(const char* const symbol)
-{
- CARLA_ASSERT(m_uiLib);
-
- if (m_uiLib)
- return lib_symbol(m_uiLib, symbol);
-
- return nullptr;
-}
-
-const char* CarlaBridgeClient::uiLibError()
-{
- return lib_error(m_uiFilename);
-}
-#endif
-
-CARLA_BRIDGE_END_NAMESPACE
diff --git a/c++/carla-bridge/carla_bridge_client.hpp b/c++/carla-bridge/carla_bridge_client.hpp
deleted file mode 100644
index 19fcc3f..0000000
--- a/c++/carla-bridge/carla_bridge_client.hpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Carla Bridge Client
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BRIDGE_CLIENT_HPP
-#define CARLA_BRIDGE_CLIENT_HPP
-
-#include "carla_bridge_osc.hpp"
-
-CARLA_BRIDGE_START_NAMESPACE
-
-#if 0
-} // Fix editor indentation
-#endif
-
-/*!
- * @defgroup CarlaBridgeClient Carla Bridge Client
- *
- * The Carla Bridge Client.
- * @{
- */
-
-class CarlaBridgeClient
-{
-public:
- CarlaBridgeClient(const char* const uiTitle);
- virtual ~CarlaBridgeClient();
-
-#ifdef BUILD_BRIDGE_UI
- // ---------------------------------------------------------------------
- // ui initialization
-
- virtual bool init(const char* const, const char* const);
- virtual void close();
-#endif
-
-#ifdef BUILD_BRIDGE_UI
- // ---------------------------------------------------------------------
- // ui management
-
- virtual void* getWidget() const = 0;
- virtual bool isResizable() const = 0;
- virtual bool needsReparent() const = 0;
-#endif
-
- // ---------------------------------------------------------------------
- // processing
-
- virtual void setParameter(const int32_t rindex, const double value) = 0;
- virtual void setProgram(const uint32_t index) = 0;
-#ifdef BUILD_BRIDGE_PLUGIN
- virtual void setMidiProgram(const uint32_t index) = 0;
-#endif
-#ifdef BUILD_BRIDGE_UI
- virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
-#endif
- virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
- virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;
-
-#ifdef BUILD_BRIDGE_PLUGIN
- // ---------------------------------------------------------------------
- // plugin
-
- virtual void saveNow() = 0;
- virtual void setCustomData(const char* const type, const char* const key, const char* const value) = 0;
- virtual void setChunkData(const char* const filePath) = 0;
-#endif
-
- // ---------------------------------------------------------------------
- // osc stuff
-
- bool oscInit(const char* const url);
- bool oscIdle();
- void oscClose();
-
- bool isOscControlRegistered() const;
- void sendOscUpdate();
-
-#ifdef BUILD_BRIDGE_PLUGIN
- void sendOscBridgeUpdate();
- void sendOscBridgeError(const char* const error);
-#endif
-
- // ---------------------------------------------------------------------
- // toolkit
-
- void toolkitShow();
- void toolkitHide();
- void toolkitResize(const int width, const int height);
- void toolkitExec(const bool showGui);
- void toolkitQuit();
-
- // ---------------------------------------------------------------------
-
-protected:
- void sendOscConfigure(const char* const key, const char* const value);
- void sendOscControl(const int32_t index, const float value);
- void sendOscProgram(const int32_t index);
- void sendOscMidiProgram(const int32_t index);
- void sendOscMidi(const uint8_t midiBuf[4]);
- void sendOscExiting();
-
-#ifdef BRIDGE_LV2
- void sendOscLv2TransferAtom(const int32_t portIndex, const char* const typeStr, const char* const atomBuf);
- void sendOscLv2TransferEvent(const int32_t portIndex, const char* const typeStr, const char* const atomBuf);
-#endif
-
- // ---------------------------------------------------------------------
-
- void* getContainerId();
-
-#ifdef BUILD_BRIDGE_UI
- bool uiLibOpen(const char* const filename);
- bool uiLibClose();
- void* uiLibSymbol(const char* const symbol);
- const char* uiLibError();
-#endif
-
- // ---------------------------------------------------------------------
-
-private:
- CarlaBridgeOsc m_osc;
- CarlaBridgeToolkit* const m_toolkit;
-
- const CarlaOscData* m_oscData;
-
-#ifdef BUILD_BRIDGE_UI
- char* m_uiFilename;
- void* m_uiLib;
- bool m_uiQuit;
-#else
- friend class CarlaPluginClient;
-#endif
-};
-
-/**@}*/
-
-CARLA_BRIDGE_END_NAMESPACE
-
-#endif // CARLA_BRIDGE_CLIENT_HPP
diff --git a/c++/carla-bridge/carla_bridge_osc.cpp b/c++/carla-bridge/carla_bridge_osc.cpp
deleted file mode 100644
index 194cc3c..0000000
--- a/c++/carla-bridge/carla_bridge_osc.cpp
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Carla Bridge OSC
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_bridge_osc.hpp"
-#include "carla_bridge_client.hpp"
-#include "carla_midi.h"
-#include "carla_utils.hpp"
-
-#include
-#include
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -----------------------------------------------------------------------
-
-CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client_)
- : client(client_)
-{
- qDebug("CarlaBridgeOsc::CarlaBridgeOsc(%p)", client);
- CARLA_ASSERT(client);
-
- m_name = nullptr;
- m_nameSize = 0;
-
- m_server = nullptr;
- m_serverPath = nullptr;
-}
-
-CarlaBridgeOsc::~CarlaBridgeOsc()
-{
- qDebug("CarlaBridgeOsc::~CarlaBridgeOsc()");
- CARLA_ASSERT(! m_name);
- CARLA_ASSERT(! m_server);
- CARLA_ASSERT(! m_serverPath);
-}
-
-bool CarlaBridgeOsc::init(const char* const url)
-{
- qDebug("CarlaBridgeOsc::init(\"%s\")", url);
- CARLA_ASSERT(! m_name);
- CARLA_ASSERT(! m_server);
- CARLA_ASSERT(! m_serverPath);
- CARLA_ASSERT(m_nameSize == 0);
- CARLA_ASSERT(url);
-
- if (! url)
- {
- qWarning("CarlaBridgeOsc::init(\"%s\") - invalid url", url);
- return false;
- }
-
-#ifdef BUILD_BRIDGE_PLUGIN
- m_name = strdup("carla-bridge-plugin");
-#else
- m_name = strdup("carla-bridge-ui");
-#endif
- m_nameSize = strlen(m_name);
-
- char* const host = lo_url_get_hostname(url);
- char* const path = lo_url_get_path(url);
- char* const port = lo_url_get_port(url);
-
- if (! host)
- {
- qCritical("CarlaBridgeOsc::init(\"%s\") - failed to get url hostname", url);
- return false;
- }
-
- if (! path)
- {
- free(host);
- qCritical("CarlaBridgeOsc::init(\"%s\") - failed to get url path", url);
- return false;
- }
-
- if (! port)
- {
- free(host);
- free(path);
- qCritical("CarlaBridgeOsc::init(\"%s\") - failed to get url port", url);
- return false;
- }
-
- m_controlData.path = path;
- m_controlData.target = lo_address_new_with_proto(LO_TCP, host, port);
-
- free(host);
- free(port);
-
- if (! m_controlData.target)
- {
- qCritical("CarlaBridgeOsc::init(\"%s\") - failed to get new url address for host '%s' and port '%s'", url, host, port);
- return false;
- }
-
- m_server = lo_server_new_with_proto(nullptr, LO_TCP, osc_error_handler);
-
- if (! m_server)
- {
- qCritical("CarlaBridgeOsc::init(\"%s\") - failed to create new OSC server", url);
- return false;
- }
-
- if (char* const serverUrl = lo_server_get_url(m_server))
- {
- m_serverPath = strdup(QString("%1%2").arg(serverUrl).arg(m_name).toUtf8().constData());
- free(serverUrl);
- }
- else
- m_serverPath = strdup(QString("%1carla-bridge").arg(serverUrl).toUtf8().constData());
-
- lo_server_add_method(m_server, nullptr, nullptr, osc_message_handler, this);
-
- return true;
-}
-
-void CarlaBridgeOsc::idle()
-{
- CARLA_ASSERT(m_server);
-
- if (m_server)
- {
- while (lo_server_recv_noblock(m_server, 0) != 0) {}
- }
-}
-
-void CarlaBridgeOsc::close()
-{
- qDebug("CarlaBridgeOsc::close()");
- CARLA_ASSERT(m_name);
- CARLA_ASSERT(m_server);
- CARLA_ASSERT(m_serverPath);
-
- m_nameSize = 0;
-
- if (m_name)
- {
- free(m_name);
- m_name = nullptr;
- }
-
- if (m_server)
- {
- lo_server_del_method(m_server, nullptr, nullptr);
- lo_server_free(m_server);
- m_server = nullptr;
- }
-
- if (m_serverPath)
- {
- free(m_serverPath);
- m_serverPath = nullptr;
- }
-
- m_controlData.free();
-}
-
-// -----------------------------------------------------------------------
-
-int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
-{
- qDebug("CarlaBridgeOsc::handleMessage(\"%s\", %i, %p, \"%s\", %p)", path, argc, argv, types, msg);
- CARLA_ASSERT(m_name);
- CARLA_ASSERT(m_server);
- CARLA_ASSERT(m_serverPath);
- CARLA_ASSERT(path);
-
- if (! path)
- {
- qCritical("CarlaBridgeOsc::handleMessage() - got invalid path");
- return 1;
- }
-
- if (! (m_name && m_server && m_serverPath))
- {
- qCritical("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received message but client is offline", path);
- return 1;
- }
-
- if (strlen(path) <= m_nameSize || strncmp(path+1, m_name, m_nameSize) != 0)
- {
- qWarning("CarlaBridgeOsc::handleMessage() - message not for this client: '%s' != '/%s/'", path, m_name);
- return 1;
- }
-
- char method[32] = { 0 };
- strncpy(method, path + (m_nameSize + 2), 31);
-
- if (method[0] == '\0')
- {
- qWarning("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received message without method", path);
- return 1;
- }
-
- // Common OSC methods
- if (strcmp(method, "configure") == 0)
- return handleMsgConfigure(argc, argv, types);
- if (strcmp(method, "control") == 0)
- return handleMsgControl(argc, argv, types);
- if (strcmp(method, "program") == 0)
- return handleMsgProgram(argc, argv, types);
- if (strcmp(method, "midi_program") == 0)
- return handleMsgMidiProgram(argc, argv, types);
- if (strcmp(method, "midi") == 0)
- return handleMsgMidi(argc, argv, types);
- if (strcmp(method, "sample-rate") == 0)
- return 0; // unused
- if (strcmp(method, "show") == 0)
- return handleMsgShow();
- if (strcmp(method, "hide") == 0)
- return handleMsgHide();
- if (strcmp(method, "quit") == 0)
- return handleMsgQuit();
-
-#ifdef BRIDGE_LV2
- // LV2 UI methods
- if (strcmp(method, "lv2_atom_transfer") == 0)
- return handleMsgLv2TransferAtom(argc, argv, types);
- if (strcmp(method, "lv2_event_transfer") == 0)
- return handleMsgLv2TransferEvent(argc, argv, types);
-#endif
-
-#ifdef BUILD_BRIDGE_PLUGIN
- // Plugin methods
- if (strcmp(method, "plugin_save_now") == 0)
- return handleMsgPluginSaveNow();
- if (strcmp(method, "plugin_set_chunk") == 0)
- return handleMsgPluginSetChunk(argc, argv, types);
- if (strcmp(method, "plugin_set_custom_data") == 0)
- return handleMsgPluginSetCustomData(argc, argv, types);
-#endif
-
-#if 0
- // TODO
- else if (strcmp(method, "set_parameter_midi_channel") == 0)
- return osc_set_parameter_midi_channel_handler(argv);
- else if (strcmp(method, "set_parameter_midi_cc") == 0)
- return osc_set_parameter_midi_channel_handler(argv);
-#endif
-
- qWarning("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received unsupported OSC method '%s'", path, method);
- return 1;
-}
-
-int CarlaBridgeOsc::handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgConfigure()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");
-
- if (! client)
- return 1;
-
- // nothing here for now
-
- return 0;
-
- Q_UNUSED(argv);
-}
-
-int CarlaBridgeOsc::handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgControl()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if");
-
- if (! client)
- return 1;
-
- const int32_t index = argv[0]->i;
- const float value = argv[1]->f;
-
- client->setParameter(index, value);
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgProgram()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");
-
- if (! client)
- return 1;
-
- const int32_t index = argv[0]->i;
-
- client->setProgram(index);
-
- return 0;
-}
-
-#ifdef BUILD_BRIDGE_PLUGIN
-int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgMidiProgram()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");
-
- if (! client)
- return 1;
-
- const int32_t index = argv[0]->i;
-
- client->setMidiProgram(index);
-
- return 0;
-}
-#else
-int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgMidiProgram()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");
-
- if (! client)
- return 1;
-
- const int32_t bank = argv[0]->i;
- const int32_t program = argv[1]->i;
-
- client->setMidiProgram(bank, program);
-
- return 0;
-}
-#endif
-
-int CarlaBridgeOsc::handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgMidi()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m");
-
- if (! client)
- return 1;
-
- const uint8_t* const mdata = argv[0]->m;
- const uint8_t data[4] = { mdata[0], mdata[1], mdata[2], mdata[3] };
-
- uint8_t status = data[1];
- uint8_t channel = status & 0x0F;
-
- // Fix bad note-off
- if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0)
- status -= 0x10;
-
- if (MIDI_IS_STATUS_NOTE_OFF(status))
- {
- const uint8_t note = data[2];
-
- client->noteOff(channel, note);
- }
- else if (MIDI_IS_STATUS_NOTE_ON(status))
- {
- const uint8_t note = data[2];
- const uint8_t velo = data[3];
-
- client->noteOn(channel, note, velo);
- }
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgShow()
-{
- qDebug("CarlaBridgeOsc::handleMsgShow()");
-
- if (! client)
- return 1;
-
- client->toolkitShow();
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgHide()
-{
- qDebug("CarlaBridgeOsc::handleMsgHide()");
-
- if (! client)
- return 1;
-
- client->toolkitHide();
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgQuit()
-{
- qDebug("CarlaBridgeOsc::handleMsgQuit()");
-
- if (! client)
- return 1;
-
- client->toolkitQuit();
-
- return 0;
-}
-
-CARLA_BRIDGE_END_NAMESPACE
diff --git a/c++/carla-bridge/carla_bridge_osc.hpp b/c++/carla-bridge/carla_bridge_osc.hpp
deleted file mode 100644
index 041c645..0000000
--- a/c++/carla-bridge/carla_bridge_osc.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Carla Bridge OSC
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BRIDGE_OSC_HPP
-#define CARLA_BRIDGE_OSC_HPP
-
-#include "carla_bridge.hpp"
-#include "carla_osc_utils.hpp"
-
-#define CARLA_BRIDGE_OSC_HANDLE_ARGS const int argc, const lo_arg* const* const argv, const char* const types
-
-#define CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
- /* check argument count */ \
- if (argc != argcToCompare) \
- { \
- qCritical("CarlaBridgeOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
- return 1; \
- } \
- if (argc > 0) \
- { \
- /* check for nullness */ \
- if (! (types && typesToCompare)) \
- { \
- qCritical("CarlaBridgeOsc::%s() - argument types are null", __FUNCTION__); \
- return 1; \
- } \
- /* check argument types */ \
- if (strcmp(types, typesToCompare) != 0) \
- { \
- qCritical("CarlaBridgeOsc::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
- return 1; \
- } \
- }
-
-CARLA_BRIDGE_START_NAMESPACE
-
-#if 0
-} // Fix editor indentation
-#endif
-
-class CarlaBridgeOsc
-{
-public:
- CarlaBridgeOsc(CarlaBridgeClient* const client);
- ~CarlaBridgeOsc();
-
- bool init(const char* const url);
- void idle();
- void close();
-
- // -------------------------------------------------------------------
-
- bool isControlRegistered() const
- {
- return bool(m_controlData.target);
- }
-
- const CarlaOscData* getControlData() const
- {
- return &m_controlData;
- }
-
- const char* getServerPath() const
- {
- return m_serverPath;
- }
-
- // -------------------------------------------------------------------
-
-private:
- CarlaBridgeClient* const client;
-
- char* m_name;
- size_t m_nameSize;
-
- lo_server m_server;
- char* m_serverPath;
-
- CarlaOscData m_controlData;
-
- // -------------------------------------------------------------------
-
- int handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);
-
- int handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgShow();
- int handleMsgHide();
- int handleMsgQuit();
-
-#ifdef BRIDGE_LV2
- int handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS);
-#endif
-
-#ifdef BUILD_BRIDGE_PLUGIN
- int handleMsgPluginSaveNow();
- int handleMsgPluginSetChunk(CARLA_BRIDGE_OSC_HANDLE_ARGS);
- int handleMsgPluginSetCustomData(CARLA_BRIDGE_OSC_HANDLE_ARGS);
-#endif
-
- // -------------------------------------------------------------------
-
- static void osc_error_handler(const int num, const char* const msg, const char* const path)
- {
- qWarning("CarlaBridgeOsc::osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
- }
-
- static int osc_message_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const user_data)
- {
- CARLA_ASSERT(user_data);
- if (CarlaBridgeOsc* const _this_ = (CarlaBridgeOsc*)user_data)
- return _this_->handleMessage(path, argc, argv, types, msg);
- return 1;
- }
-};
-
-CARLA_BRIDGE_END_NAMESPACE
-
-#endif // CARLA_BRIDGE_OSC_HPP
diff --git a/c++/carla-bridge/carla_bridge_plugin.cpp b/c++/carla-bridge/carla_bridge_plugin.cpp
deleted file mode 100644
index 91ea99b..0000000
--- a/c++/carla-bridge/carla_bridge_plugin.cpp
+++ /dev/null
@@ -1,1150 +0,0 @@
-/*
- * Carla Plugin bridge code
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifdef BRIDGE_PLUGIN
-
-#include "carla_bridge_client.hpp"
-#include "carla_bridge_toolkit.hpp"
-#include "carla_plugin.hpp"
-#include "../carla/Shared.hpp"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
-# include
-#else
-# include
-#endif
-
-#ifdef Q_OS_UNIX
-# include
-#endif
-
-// -------------------------------------------------------------------------
-
-static int qargc = 0;
-static char** qargv = nullptr;
-static bool qCloseNow = false;
-static bool qSaveNow = false;
-
-#if defined(Q_OS_HAIKU) || defined(Q_OS_UNIX)
-void closeSignalHandler(int)
-{
- qCloseNow = true;
-}
-void saveSignalHandler(int)
-{
- qSaveNow = true;
-}
-#elif defined(Q_OS_WIN)
-BOOL WINAPI closeSignalHandler(DWORD dwCtrlType)
-{
- if (dwCtrlType == CTRL_C_EVENT)
- {
- qCloseNow = true;
- return TRUE;
- }
-
- return FALSE;
-}
-#endif
-
-void initSignalHandler()
-{
-#if defined(Q_OS_HAIKU) || defined(Q_OS_UNIX)
- struct sigaction sint;
- struct sigaction sterm;
- struct sigaction susr1;
-
- sint.sa_handler = closeSignalHandler;
- sint.sa_flags = SA_RESTART;
- sint.sa_restorer = nullptr;
- sigemptyset(&sint.sa_mask);
- sigaction(SIGINT, &sint, nullptr);
-
- sterm.sa_handler = closeSignalHandler;
- sterm.sa_flags = SA_RESTART;
- sterm.sa_restorer = nullptr;
- sigemptyset(&sterm.sa_mask);
- sigaction(SIGTERM, &sterm, nullptr);
-
- susr1.sa_handler = saveSignalHandler;
- susr1.sa_flags = SA_RESTART;
- susr1.sa_restorer = nullptr;
- sigemptyset(&susr1.sa_mask);
- sigaction(SIGUSR1, &susr1, nullptr);
-#elif defined(Q_OS_WIN)
- SetConsoleCtrlHandler(closeSignalHandler, TRUE);
-#endif
-}
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -------------------------------------------------------------------------
-
-class CarlaBridgeToolkitPlugin : public CarlaBridgeToolkit,
- public CarlaBackend::CarlaPluginGUI::Callback
-{
-public:
- CarlaBridgeToolkitPlugin(CarlaBridgeClient* const client, const char* const uiTitle)
- : CarlaBridgeToolkit(client, uiTitle)
- {
- qDebug("CarlaBridgeToolkitPlugin::CarlaBridgeToolkitPlugin(%p, \"%s\")", client, uiTitle);
-
- app = nullptr;
- gui = nullptr;
-
- m_hasUI = false;
- m_uiQuit = false;
- m_uiShow = false;
-
- init();
- }
-
- ~CarlaBridgeToolkitPlugin()
- {
- qDebug("CarlaBridgeToolkitPlugin::~CarlaBridgeToolkitPlugin()");
-
- if (gui)
- {
- gui->close();
-
- delete gui;
- gui = nullptr;
- }
-
- if (app)
- {
- if (! app->closingDown())
- app->quit();
-
- delete app;
- app = nullptr;
- }
- }
-
- void init()
- {
- qDebug("CarlaBridgeToolkitPlugin::init()");
- CARLA_ASSERT(! app);
- CARLA_ASSERT(! gui);
-
- app = new QApplication(qargc, qargv);
-
- gui = new CarlaBackend::CarlaPluginGUI(nullptr, this);
- }
-
- void exec(const bool showGui)
- {
- qDebug("CarlaBridgeToolkitPlugin::exec(%s)", bool2str(showGui));
- CARLA_ASSERT(app);
- CARLA_ASSERT(gui);
- CARLA_ASSERT(client);
-
- if (showGui)
- {
- if (m_hasUI)
- show();
- }
- else
- {
- app->setQuitOnLastWindowClosed(false);
- client->sendOscUpdate();
- client->sendOscBridgeUpdate();
- }
-
- m_uiQuit = showGui;
-
- // Main loop
- app->exec();
- }
-
- void quit()
- {
- qDebug("CarlaBridgeToolkitPlugin::quit()");
- CARLA_ASSERT(app);
-
- if (app && ! app->closingDown())
- app->quit();
- }
-
- void show();
- void hide();
-
- void resize(const int width, const int height)
- {
- qDebug("CarlaBridgeToolkitPlugin::resize(%i, %i)", width, height);
- CARLA_ASSERT(gui);
-
- if (gui)
- gui->setNewSize(width, height);
- }
-
- GuiContainer* getContainer() const
- {
- CARLA_ASSERT(gui);
-
- if (gui)
- return gui->getContainer();
-
- return nullptr;
- }
-
- void* getContainerId()
- {
- CARLA_ASSERT(gui);
-
- if (gui)
- return (void*)gui->getWinId();
-
- return nullptr;
- }
-
- void setHasUI(const bool hasUI, const bool showUI)
- {
- m_hasUI = hasUI;
- m_uiShow = showUI;
- }
-
- void guiClosedCallback();
-
-protected:
- QApplication* app;
- CarlaBackend::CarlaPluginGUI* gui;
-
-private:
- bool m_hasUI;
- bool m_uiQuit;
- bool m_uiShow;
-};
-
-CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
-{
- return new CarlaBridgeToolkitPlugin(client, uiTitle);
-}
-
-// -------------------------------------------------------------------------
-
-class CarlaPluginClient : public CarlaBridgeClient,
- public QObject
-{
-public:
- CarlaPluginClient()
- : CarlaBridgeClient(""),
- QObject(nullptr)
- {
- qDebug("CarlaPluginClient::CarlaPluginClient()");
-
- msgTimerGUI = 0;
- msgTimerOSC = 0;
-
- needsResize = 0;
- nextWidth = 0;
- nextHeight = 0;
-
- engine = nullptr;
- plugin = nullptr;
- }
-
- ~CarlaPluginClient()
- {
- qDebug("CarlaPluginClient::~CarlaPluginClient()");
- CARLA_ASSERT(msgTimerGUI == 0);
- CARLA_ASSERT(msgTimerOSC == 0);
- }
-
- // ---------------------------------------------------------------------
-
- void init()
- {
- CARLA_ASSERT(plugin);
-
- msgTimerGUI = startTimer(50);
- msgTimerOSC = startTimer(25);
-
- if (! plugin)
- return;
-
- bool guiResizable;
- CarlaBackend::GuiType guiType;
- plugin->getGuiInfo(&guiType, &guiResizable);
-
- CarlaBridgeToolkitPlugin* const plugToolkit = (CarlaBridgeToolkitPlugin*)m_toolkit;
-
- if (guiType == CarlaBackend::GUI_INTERNAL_QT4 || guiType == CarlaBackend::GUI_INTERNAL_COCOA || guiType == CarlaBackend::GUI_INTERNAL_HWND || guiType == CarlaBackend::GUI_INTERNAL_X11)
- {
- plugin->setGuiContainer(plugToolkit->getContainer());
- plugToolkit->setHasUI(true, true);
- }
- else
- {
- plugToolkit->setHasUI(guiType != CarlaBackend::GUI_NONE, false);
- }
- }
-
- void quit()
- {
- engine = nullptr;
- plugin = nullptr;
-
- if (msgTimerGUI != 0)
- {
- killTimer(msgTimerGUI);
- msgTimerGUI = 0;
- }
-
- if (msgTimerOSC != 0)
- {
- killTimer(msgTimerOSC);
- msgTimerOSC = 0;
- }
- }
-
- // ---------------------------------------------------------------------
-
- void setEngine(CarlaBackend::CarlaEngine* const engine)
- {
- qDebug("CarlaPluginClient::setEngine(%p)", engine);
- CARLA_ASSERT(engine);
-
- this->engine = engine;
-
- engine->setOscBridgeData(m_oscData);
- }
-
- void setPlugin(CarlaBackend::CarlaPlugin* const plugin)
- {
- qDebug("CarlaPluginClient::setPlugin(%p)", plugin);
- CARLA_ASSERT(plugin);
-
- this->plugin = plugin;
-
- // load carla plugin preset if possible
- if (const char* const pName = plugin->name())
- {
- QFile pFile(QDir::currentPath() + QDir::separator() + pName + ".carxs");
- qDebug("Trying to load plugin preset file '%s'", pFile.fileName().toUtf8().constData());
-
- if (! /*(*/pFile.exists() /*&& pFile.isReadable())*/)
- {
- qDebug("Plugin preset file doesn't exist or is not readable");
- return;
- }
-
- if (! pFile.open(QFile::ReadOnly))
- {
- qWarning("Plugin preset file read failed");
- return;
- }
-
- QDomDocument xml;
- xml.setContent(pFile.readAll());
-
- QDomElement xmlNode(xml.documentElement());
-
- if (xmlNode.tagName() == "CARLA-PRESET")
- {
- loadStateDict(getSaveStateDictFromXML(xmlNode));
- }
- else
- qWarning("Plugin preset file is not valid or corrupted");
-
- pFile.close();
- }
- }
-
- // ---------------------------------------------------------------------
-
- void loadStateDict(const CarlaSaveState* const content)
- {
- CARLA_ASSERT(content);
-
- if (! content)
- return;
-
- qDebug("Loading plugin state now...");
-
- // ---------------------------------------------------------------------
- // Part 1 - set custom data (except chunks)
-
- foreach (const CarlaStateCustomData& customData, content->customData)
- {
- if (customData.type != CUSTOM_DATA_CHUNK)
- {
- const char* const type = customData.type.toUtf8().constData();
- const char* const key = customData.key.toUtf8().constData();
- const char* const value = customData.value.toUtf8().constData();
-
- plugin->setCustomData(type, key, value, true);
- }
- }
-
- // ---------------------------------------------------------------------
- // Part 2 - set program
-
- int32_t programId = -1;
-
- if (! content->currentProgramName.isEmpty())
- {
- const uint32_t programCount = plugin->programCount();
-
- char strBuf[STR_MAX] = { 0 };
- plugin->getProgramName(content->currentProgramIndex, strBuf);
- QString testProgramName(strBuf);
-
- // Program name matches
- if (content->currentProgramName == testProgramName)
- {
- programId = content->currentProgramIndex;
- }
-
- // index < count
- else if (content->currentProgramIndex < (int32_t)programCount)
- {
- programId = content->currentProgramIndex;
- }
-
- // index not valid, try to find by name
- else
- {
- for (uint32_t i=0; i < programCount; i++)
- {
- plugin->getProgramName(i, strBuf);
- testProgramName = QString(strBuf);
-
- if (content->currentProgramName == testProgramName)
- {
- programId = i;
- break;
- }
- }
- }
- }
-
- // set program now, if valid
- if (programId >= 0)
- {
- plugin->setProgram(programId, true, true, false, true);
- }
-
- // ---------------------------------------------------------------------
- // Part 3 - set midi program
-
- if (content->currentMidiBank >= 0 and content->currentMidiProgram >= 0)
- {
- const uint32_t midiProgramCount = plugin->midiProgramCount();
-
- for (uint32_t i=0; i < midiProgramCount; i++)
- {
- const MidiProgramData* const midiProgramData = plugin->midiProgramData(i);
-
- if ((int32_t)midiProgramData->bank == content->currentMidiBank && (int32_t)midiProgramData->program == content->currentMidiProgram)
- {
- plugin->setMidiProgram(i, true, true, false, true);
- break;
- }
- }
- }
-
- // ---------------------------------------------------------------------
- // Part 4a - get plugin parameter symbols
-
- struct ParamSymbol {
- uint32_t index;
- QString symbol;
-
- ParamSymbol() {}
-
- ParamSymbol(uint32_t index_, const char* symbol_)
- : index(index_),
- symbol(symbol_) {}
- };
-
- QVector paramSymbols;
-
- foreach (const CarlaStateParameter& parameter, content->parameters)
- {
- if (! parameter.symbol.isEmpty())
- {
- char strBuf[STR_MAX] = { 0 };
- plugin->getParameterSymbol(parameter.index, strBuf);
-
- if (strBuf[0] != 0)
- {
- ParamSymbol ps(parameter.index, strBuf);
- paramSymbols.append(ps);
- }
- }
- }
-
- // ---------------------------------------------------------------------
- // Part 4b - set parameter values (carefully)
-
- const double sampleRate = engine->getSampleRate();
-
- foreach (const CarlaStateParameter& parameter, content->parameters)
- {
- int32_t index = -1;
-
- if (content->type == "LADSPA")
- {
- // Try to set by symbol, otherwise use index
- if (! parameter.symbol.isEmpty())
- {
- bool breaked = false;
-
- foreach (const ParamSymbol& ps, paramSymbols)
- {
- if (parameter.symbol == ps.symbol)
- {
- index = ps.index;
- breaked = true;
- break;
- }
- }
-
- if (! breaked)
- index = parameter.index;
- }
- else
- index = parameter.index;
- }
- else if (content->type == "LV2")
- {
- // Symbol only
- if (! parameter.symbol.isEmpty())
- {
- bool breaked = false;
-
- foreach (const ParamSymbol& ps, paramSymbols)
- {
- if (parameter.symbol == ps.symbol)
- {
- index = ps.index;
- breaked = true;
- break;
- }
- }
-
- if (! breaked)
- qWarning("Failed to find LV2 parameter symbol for '%s')", parameter.symbol.toUtf8().constData());
- }
- else
- qWarning("LV2 Plugin parameter '%s' has no symbol", parameter.name.toUtf8().constData());
- }
- else
- {
- // Index only
- index = parameter.index;
- }
-
- // Now set parameter
- if (index >= 0)
- {
- const ParameterData* const paramData = plugin->parameterData(index);
- double value = parameter.value;
-
- if (paramData->hints & PARAMETER_USES_SAMPLERATE)
- value *= sampleRate;
-
- plugin->setParameterValue(index, value, true, true, false);
- plugin->setParameterMidiCC(index, parameter.midiCC, true, false);
- plugin->setParameterMidiChannel(index, parameter.midiChannel-1, true, false);
- }
- else
- qWarning("Could not set parameter data for '%s')", parameter.name.toUtf8().constData());
- }
-
- // ---------------------------------------------------------------------
- // Part 5 - set chunk data
-
- foreach (const CarlaStateCustomData& customData, content->customData)
- {
- if (customData.type == CUSTOM_DATA_CHUNK)
- {
- const char* const type = customData.type.toUtf8().constData();
- const char* const key = customData.key.toUtf8().constData();
- const char* const value = customData.value.toUtf8().constData();
-
- plugin->setCustomData(type, key, value, true);
- }
- }
-
- if (! content->chunk.isEmpty())
- plugin->setChunkData(content->chunk.toUtf8().constData());
-
- qDebug("Loading plugin state now finished");
- }
-
- void guiClosed()
- {
- CARLA_ASSERT(engine);
-
- if (engine)
- engine->osc_send_bridge_configure(CarlaBackend::CARLA_BRIDGE_MSG_HIDE_GUI, "");
- }
-
- void showPluginGui(const bool yesNo)
- {
- CARLA_ASSERT(plugin);
-
- if (plugin)
- plugin->showGui(yesNo);
- }
-
- // ---------------------------------------------------------------------
- // processing
-
- void setParameter(const int32_t rindex, const double value)
- {
- qDebug("CarlaPluginClient::setParameter(%i, %g)", rindex, value);
- CARLA_ASSERT(plugin);
-
- if (plugin)
- plugin->setParameterValueByRIndex(rindex, value, true, true, false);
- }
-
- void setProgram(const uint32_t index)
- {
- qDebug("CarlaPluginClient::setProgram(%i)", index);
- CARLA_ASSERT(engine);
- CARLA_ASSERT(plugin);
- CARLA_ASSERT(index < plugin->programCount());
-
- if (! (plugin && engine))
- return;
- if (index >= plugin->programCount())
- return;
-
- plugin->setProgram(index, true, true, false, true);
-
- double value;
- for (uint32_t i=0; i < plugin->parameterCount(); i++)
- {
- value = plugin->getParameterValue(i);
- engine->osc_send_bridge_set_parameter_value(i, value);
- engine->osc_send_bridge_set_default_value(i, value);
- }
- }
-
- void setMidiProgram(const uint32_t index)
- {
- qDebug("CarlaPluginClient::setMidiProgram(%i)", index);
- CARLA_ASSERT(engine);
- CARLA_ASSERT(plugin);
-
- if (! (plugin && engine))
- return;
-
- plugin->setMidiProgram(index, true, true, false, true);
-
- double value;
- for (uint32_t i=0; i < plugin->parameterCount(); i++)
- {
- value = plugin->getParameterValue(i);
- engine->osc_send_bridge_set_parameter_value(i, value);
- engine->osc_send_bridge_set_default_value(i, value);
- }
- }
-
- void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
- {
- qDebug("CarlaPluginClient::noteOn(%i, %i, %i)", channel, note, velo);
- CARLA_ASSERT(plugin);
- CARLA_ASSERT(velo > 0);
-
- if (! plugin)
- return;
-
- plugin->sendMidiSingleNote(channel, note, velo, true, true, false);
- }
-
- void noteOff(const uint8_t channel, const uint8_t note)
- {
- qDebug("CarlaPluginClient::noteOff(%i, %i)", channel, note);
- CARLA_ASSERT(plugin);
-
- if (! plugin)
- return;
-
- plugin->sendMidiSingleNote(channel, note, 0, true, true, false);
- }
-
- // ---------------------------------------------------------------------
- // plugin
-
- void saveNow()
- {
- qDebug("CarlaPluginClient::saveNow()");
- CARLA_ASSERT(plugin);
- CARLA_ASSERT(engine);
-
- if (! (plugin && engine))
- return;
-
- plugin->prepareForSave();
-
- for (uint32_t i=0; i < plugin->customDataCount(); i++)
- {
- const CarlaBackend::CustomData* const cdata = plugin->customData(i);
- engine->osc_send_bridge_set_custom_data(cdata->type, cdata->key, cdata->value);
- }
-
- if (plugin->hints() & CarlaBackend::PLUGIN_USES_CHUNKS)
- {
- void* data = nullptr;
- int32_t dataSize = plugin->chunkData(&data);
-
- if (data && dataSize >= 4)
- {
- QString filePath;
- filePath = QDir::tempPath();
-#ifdef Q_OS_WIN
- filePath += "\\.CarlaChunk_";
-#else
- filePath += "/.CarlaChunk_";
-#endif
- filePath += plugin->name();
-
- QFile file(filePath);
-
- if (file.open(QIODevice::WriteOnly))
- {
- QByteArray chunk((const char*)data, dataSize);
- file.write(chunk);
- file.close();
- engine->osc_send_bridge_set_chunk_data(filePath.toUtf8().constData());
- }
- }
- }
-
- engine->osc_send_bridge_configure(CarlaBackend::CARLA_BRIDGE_MSG_SAVED, "");
- }
-
- void setCustomData(const char* const type, const char* const key, const char* const value)
- {
- qDebug("CarlaPluginClient::setCustomData(\"%s\", \"%s\", \"%s\")", type, key, value);
- CARLA_ASSERT(plugin);
-
- if (! plugin)
- return;
-
- plugin->setCustomData(type, key, value, true);
- }
-
- void setChunkData(const char* const filePath)
- {
- qDebug("CarlaPluginClient::setChunkData(\"%s\")", filePath);
- CARLA_ASSERT(plugin);
-
- if (! plugin)
- return;
-
- QString chunkFilePath(filePath);
-
-#ifdef Q_OS_WIN
- if (chunkFilePath.startsWith("/"))
- {
- // running under Wine, posix host
- chunkFilePath = chunkFilePath.replace(0, 1, "Z:/");
- chunkFilePath = QDir::toNativeSeparators(chunkFilePath);
- }
-#endif
- QFile chunkFile(chunkFilePath);
-
- if (plugin && chunkFile.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QTextStream in(&chunkFile);
- QString stringData(in.readAll());
- chunkFile.close();
- chunkFile.remove();
-
- plugin->setChunkData(stringData.toUtf8().constData());
- }
- }
-
- // ---------------------------------------------------------------------
- // callback
-
- static void callback(void* const ptr, CarlaBackend::CallbackType const action, const unsigned short, const int value1, const int value2, const double value3, const char* const valueStr)
- {
- CARLA_ASSERT(ptr);
-
- if (CarlaPluginClient* const _this_ = (CarlaPluginClient*)ptr)
- _this_->handleCallback(action, value1, value2, value3, valueStr);
- }
-
- // ---------------------------------------------------------------------
-
-protected:
- int msgTimerGUI;
- int msgTimerOSC;
-
- bool needsResize;
- int nextWidth;
- int nextHeight;
-
- CarlaBackend::CarlaEngine* engine;
- CarlaBackend::CarlaPlugin* plugin;
-
- std::set parametersToUpdate;
-
- void handleCallback(const CarlaBackend::CallbackType action, const int value1, const int value2, const double value3, const char* const valueStr)
- {
- CARLA_BACKEND_USE_NAMESPACE
- qDebug("CarlaPluginClient::handleCallback(%s, %i, %i, %g \"%s\")", CallbackType2Str(action), value1, value2, value3, valueStr);
-
- if (! engine)
- return;
-
- switch (action)
- {
- case CALLBACK_DEBUG:
- break;
-
- case CALLBACK_PARAMETER_VALUE_CHANGED:
- parametersToUpdate.insert(value1);
- break;
-
- case CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED:
- // todo, unused?
- break;
-
- case CALLBACK_PARAMETER_MIDI_CC_CHANGED:
- // todo, unused?
- break;
-
- case CALLBACK_PROGRAM_CHANGED:
- engine->osc_send_bridge_set_program(value1);
- break;
-
- case CALLBACK_MIDI_PROGRAM_CHANGED:
- engine->osc_send_bridge_set_midi_program(value1);
- break;
-
- case CALLBACK_NOTE_ON:
- // todo
- break;
-
- case CALLBACK_NOTE_OFF:
- // todo
- break;
-
- case CALLBACK_SHOW_GUI:
- if (value1 == 0)
- {
- CarlaBridgeToolkitPlugin* const plugToolkit = (CarlaBridgeToolkitPlugin*)m_toolkit;
- plugToolkit->guiClosedCallback();
- }
- break;
-
- case CALLBACK_RESIZE_GUI:
- nextWidth = value1;
- nextHeight = value2;
- needsResize = true;
- break;
-
- case CALLBACK_UPDATE:
- // todo
- break;
-
- case CALLBACK_RELOAD_INFO:
- // todo
- break;
-
- case CALLBACK_RELOAD_PARAMETERS:
- // todo
- break;
-
- case CALLBACK_RELOAD_PROGRAMS:
- // todo
- break;
-
- case CALLBACK_RELOAD_ALL:
- // todo
- break;
-
- case CALLBACK_NSM_ANNOUNCE:
- case CALLBACK_NSM_OPEN1:
- case CALLBACK_NSM_OPEN2:
- case CALLBACK_NSM_SAVE:
- break;
-
- case CALLBACK_ERROR:
- break;
-
- case CALLBACK_QUIT:
- m_toolkit->quit();
- break;
- }
- }
-
- void timerEvent(QTimerEvent* const event)
- {
- if (qCloseNow)
- return toolkitQuit();
-
- if (qSaveNow)
- {
- // TODO
- qSaveNow = false;
- }
-
- if (event->timerId() == msgTimerGUI)
- {
- if (plugin)
- plugin->idleGui();
- }
- else if (event->timerId() == msgTimerOSC)
- {
- if (isOscControlRegistered())
- oscIdle();
- }
-
- QObject::timerEvent(event);
- }
-};
-
-// -------------------------------------------------------------------------
-
-void CarlaBridgeToolkitPlugin::show()
-{
- qDebug("CarlaBridgeToolkitPlugin::show()");
- CARLA_ASSERT(gui);
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
-
- plugClient->showPluginGui(true);
-
- if (gui && m_uiShow)
- gui->setVisible(true);
-}
-
-void CarlaBridgeToolkitPlugin::hide()
-{
- qDebug("CarlaBridgeToolkitPlugin::hide()");
- CARLA_ASSERT(gui);
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
-
- if (gui && m_uiShow)
- gui->setVisible(false);
-
- plugClient->showPluginGui(false);
-}
-
-void CarlaBridgeToolkitPlugin::guiClosedCallback()
-{
- qDebug("CarlaBridgeToolkitPlugin::guiClosedCallback()");
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
-
- if (m_uiQuit)
- {
- plugClient->quit();
- quit();
- }
- else
- {
- plugClient->guiClosed();
- }
-}
-
-// -------------------------------------------------------------------------
-
-int CarlaBridgeOsc::handleMsgPluginSaveNow()
-{
- qDebug("CarlaBridgeOsc::handleMsgPluginSaveNow()");
-
- if (! client)
- return 1;
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
- plugClient->saveNow();
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgPluginSetChunk(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgPluginSaveNow()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "s");
-
- if (! client)
- return 1;
-
- const char* const chunkFile = (const char*)&argv[0]->s;
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
- plugClient->setChunkData(chunkFile);
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgPluginSetCustomData(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgPluginSaveNow()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "sss");
-
- if (! client)
- return 1;
-
- const char* const type = (const char*)&argv[0]->s;
- const char* const key = (const char*)&argv[1]->s;
- const char* const value = (const char*)&argv[2]->s;
-
- CarlaPluginClient* const plugClient = (CarlaPluginClient*)client;
- plugClient->setCustomData(type, key, value);
-
- return 0;
-}
-
-// -------------------------------------------------------------------------
-
-CARLA_BRIDGE_END_NAMESPACE
-
-int main(int argc, char* argv[])
-{
- CARLA_BRIDGE_USE_NAMESPACE
-
- if (argc != 6)
- {
- qWarning("usage: %s ", argv[0]);
- return 1;
- }
-
- const char* const oscUrl = argv[1];
- const char* const stype = argv[2];
- const char* const filename = argv[3];
- const char* name = argv[4];
- const char* const label = argv[5];
-
- const bool useOsc = strcmp(oscUrl, "null");
-
- if (strcmp(name, "(none)") == 0)
- name = nullptr;
-
- CarlaBackend::PluginType itype;
-
- if (strcmp(stype, "LADSPA") == 0)
- itype = CarlaBackend::PLUGIN_LADSPA;
- else if (strcmp(stype, "DSSI") == 0)
- itype = CarlaBackend::PLUGIN_DSSI;
- else if (strcmp(stype, "LV2") == 0)
- itype = CarlaBackend::PLUGIN_LV2;
- else if (strcmp(stype, "VST") == 0)
- itype = CarlaBackend::PLUGIN_VST;
- else
- {
- qWarning("Invalid plugin type '%s'", stype);
- return 1;
- }
-
- // Init Plugin client
- CarlaPluginClient client;
-
- // Init OSC
- if (useOsc && ! client.oscInit(oscUrl))
- {
- return 1;
- }
-
- // Listen for ctrl+c or sigint/sigterm events
- initSignalHandler();
-
- // Init backend engine
- CarlaBackend::CarlaEngine* engine = CarlaBackend::CarlaEngine::newDriverByName("JACK");
- engine->setCallback(client.callback, &client);
- client.setEngine(engine);
-
- // Init engine
- CarlaString engName(name ? name : label);
- engName += " (master)";
- engName.toBasic();
- engName.truncate(engine->maxClientNameSize());
-
- if (! engine->init(engName))
- {
- if (const char* const lastError = engine->getLastError())
- {
- qWarning("Bridge engine failed to start, error was:\n%s", lastError);
- client.sendOscBridgeError(lastError);
- }
-
- engine->close();
- delete engine;
-
- return 2;
- }
-
- void* extraStuff = nullptr;
-
- if (itype == CarlaBackend::PLUGIN_DSSI)
- extraStuff = findDSSIGUI(filename, name, label);
-
- // Init plugin
- short id = engine->addPlugin(itype, filename, name, label, extraStuff);
- int ret;
-
- if (id >= 0 && id < CarlaBackend::MAX_PLUGINS)
- {
- CarlaBackend::CarlaPlugin* const plugin = engine->getPlugin(id);
- client.setPlugin(plugin);
-
- if (! useOsc)
- plugin->setActive(true, false, false);
-
- client.init();
- client.toolkitExec(!useOsc);
- client.quit();
-
- ret = 0;
- }
- else
- {
- const char* const lastError = engine->getLastError();
- qWarning("Plugin failed to load, error was:\n%s", lastError);
-
- if (useOsc)
- client.sendOscBridgeError(lastError);
-
- ret = 1;
- }
-
- if (extraStuff && itype == CarlaBackend::PLUGIN_DSSI)
- free((char*)extraStuff);
-
- engine->aboutToClose();
- engine->removeAllPlugins();
- engine->close();
- delete engine;
-
- // Close OSC
- if (useOsc)
- {
- client.oscClose();
- }
-
- return ret;
-}
-
-#endif // BRIDGE_PLUGIN
diff --git a/c++/carla-bridge/carla_bridge_toolkit-gtk.cpp b/c++/carla-bridge/carla_bridge_toolkit-gtk.cpp
deleted file mode 100644
index 1a881b7..0000000
--- a/c++/carla-bridge/carla_bridge_toolkit-gtk.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Carla UI bridge code
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_bridge_client.hpp"
-#include "carla_bridge_toolkit.hpp"
-
-#if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
-# error Embed UI uses Qt
-#endif
-
-#include
-#include
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -------------------------------------------------------------------------
-
-#if defined(BRIDGE_GTK2)
-static const char* const appName = "Carla-Gtk2UIs";
-#elif defined(BRIDGE_GTK3)
-static const char* const appName = "Carla-Gtk3UIs";
-#else
-static const char* const appName = "Carla-UIs";
-#endif
-
-static int gargc = 0;
-static char** gargv = {};
-
-// -------------------------------------------------------------------------
-
-class CarlaToolkitGtk : public CarlaBridgeToolkit
-{
-public:
- CarlaToolkitGtk(CarlaBridgeClient* const client, const char* const uiTitle)
- : CarlaBridgeToolkit(client, uiTitle),
- settings("Cadence", appName)
- {
- qDebug("CarlaToolkitGtk::CarlaToolkitGtk(%p, \"%s\")", client, uiTitle);
-
- window = nullptr;
-
- lastX = 0;
- lastY = 0;
- lastWidth = 0;
- lastHeight = 0;
- }
-
- ~CarlaToolkitGtk()
- {
- qDebug("CarlaToolkitGtk::~CarlaToolkitGtk()");
-
- if (window)
- gtk_widget_destroy(window);
- }
-
- void init()
- {
- qDebug("CarlaToolkitGtk::init()");
- CARLA_ASSERT(! window);
-
- gtk_init(&gargc, &gargv);
-
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_resize(GTK_WINDOW(window), 30, 30);
- gtk_widget_hide(window);
- }
-
- void exec(const bool showGui)
- {
- qDebug("CarlaToolkitGtk::exec(%s)", bool2str(showGui));
- CARLA_ASSERT(window);
- CARLA_ASSERT(client);
-
- GtkWidget* const widget = (GtkWidget*)client->getWidget();
-
- gtk_container_add(GTK_CONTAINER(window), widget);
-
- gtk_window_set_resizable(GTK_WINDOW(window), client->isResizable());
- gtk_window_set_title(GTK_WINDOW(window), uiTitle);
-
- if (settings.contains(QString("%1/pos_x").arg(uiTitle)))
- {
- gtk_window_get_position(GTK_WINDOW(window), &lastX, &lastY);
-
- bool hasX, hasY;
- lastX = settings.value(QString("%1/pos_x").arg(uiTitle), lastX).toInt(&hasX);
- lastY = settings.value(QString("%1/pos_y").arg(uiTitle), lastY).toInt(&hasY);
-
- if (hasX && hasY)
- gtk_window_move(GTK_WINDOW(window), lastX, lastY);
-
- if (client->isResizable())
- {
- gtk_window_get_size(GTK_WINDOW(window), &lastWidth, &lastHeight);
-
- bool hasWidth, hasHeight;
- lastWidth = settings.value(QString("%1/width").arg(uiTitle), lastWidth).toInt(&hasWidth);
- lastHeight = settings.value(QString("%1/height").arg(uiTitle), lastHeight).toInt(&hasHeight);
-
- if (hasWidth && hasHeight)
- gtk_window_resize(GTK_WINDOW(window), lastWidth, lastHeight);
- }
- }
-
- if (showGui)
- show();
- else
- client->sendOscUpdate();
-
- // Timer
- g_timeout_add(50, gtk_ui_timeout, this);
- g_signal_connect(window, "destroy", G_CALLBACK(gtk_ui_destroy), this);
-
- // First idle
- handleTimeout();
-
- // Main loop
- gtk_main();
- }
-
- void quit()
- {
- qDebug("CarlaToolkitGtk::quit()");
-
- if (window)
- {
- gtk_widget_destroy(window);
- gtk_main_quit();
-
- window = nullptr;
- }
- }
-
- void show()
- {
- qDebug("CarlaToolkitGtk::show()");
- CARLA_ASSERT(window);
-
- if (window)
- gtk_widget_show_all(window);
- }
-
- void hide()
- {
- qDebug("CarlaToolkitGtk::hide()");
- CARLA_ASSERT(window);
-
- if (window)
- {
-#ifdef BRIDGE_GTK2
- gtk_widget_hide_all(window);
-#else
- gtk_widget_hide(window);
-#endif
- }
- }
-
- void resize(int width, int height)
- {
- qDebug("CarlaToolkitGtk::resize(%i, %i)", width, height);
- CARLA_ASSERT(window);
-
- if (window)
- gtk_window_resize(GTK_WINDOW(window), width, height);
- }
-
- // ---------------------------------------------------------------------
-
-protected:
- GtkWidget* window;
- QSettings settings;
-
- gint lastX, lastY, lastWidth, lastHeight;
-
- void handleDestroy()
- {
- qDebug("CarlaToolkitGtk::handleDestroy()");
-
- window = nullptr;
-
- settings.setValue(QString("%1/pos_x").arg(uiTitle), lastX);
- settings.setValue(QString("%1/pos_y").arg(uiTitle), lastY);
- settings.setValue(QString("%1/width").arg(uiTitle), lastWidth);
- settings.setValue(QString("%1/height").arg(uiTitle), lastHeight);
- settings.sync();
- }
-
- gboolean handleTimeout()
- {
- if (window)
- {
- gtk_window_get_position(GTK_WINDOW(window), &lastX, &lastY);
- gtk_window_get_size(GTK_WINDOW(window), &lastWidth, &lastHeight);
- }
-
- // FIXME?
- return client->isOscControlRegistered() ? client->oscIdle() : false;
- }
-
- // ---------------------------------------------------------------------
-
-private:
- static void gtk_ui_destroy(GtkWidget*, gpointer data)
- {
- CARLA_ASSERT(data);
-
- if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
- _this_->handleDestroy();
-
- gtk_main_quit();
- }
-
- static gboolean gtk_ui_timeout(gpointer data)
- {
- CARLA_ASSERT(data);
-
- if (CarlaToolkitGtk* const _this_ = (CarlaToolkitGtk*)data)
- return _this_->handleTimeout();
-
- return false;
- }
-};
-
-// -------------------------------------------------------------------------
-
-CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
-{
- return new CarlaToolkitGtk(client, uiTitle);
-}
-
-CARLA_BRIDGE_END_NAMESPACE
diff --git a/c++/carla-bridge/carla_bridge_toolkit-qt.cpp b/c++/carla-bridge/carla_bridge_toolkit-qt.cpp
deleted file mode 100644
index 762326f..0000000
--- a/c++/carla-bridge/carla_bridge_toolkit-qt.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Carla Bridge Toolkit, Qt version
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_bridge_client.hpp"
-#include "carla_bridge_toolkit.hpp"
-
-#include
-#include
-#include
-
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
-# include
-# include
-# ifdef Q_WS_X11
-# undef Q_WS_X11
-# endif
-#else
-# include
-# include
-# ifdef Q_WS_X11
-# include
-# endif
-#endif
-
-#if defined(BRIDGE_COCOA) || defined(BRIDGE_HWND) || defined(BRIDGE_X11)
-# define BRIDGE_CONTAINER
-# ifdef Q_WS_X11
-typedef QX11EmbedContainer QEmbedContainer;
-# else
-typedef QWidget QEmbedContainer;
-# endif
-#endif
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -------------------------------------------------------------------------
-
-#if defined(BRIDGE_QT4)
-static const char* const appName = "Carla-Qt4UIs";
-#elif defined(BRIDGE_QT5)
-static const char* const appName = "Carla-Qt5UIs";
-#elif defined(BRIDGE_COCOA)
-static const char* const appName = "Carla-CocoaUIs";
-#elif defined(BRIDGE_HWND)
-static const char* const appName = "Carla-HWNDUIs";
-#elif defined(BRIDGE_X11)
-static const char* const appName = "Carla-X11UIs";
-#else
-static const char* const appName = "Carla-UIs";
-#endif
-
-static int qargc = 0;
-static char* qargv[0] = {};
-
-// -------------------------------------------------------------------------
-
-class CarlaBridgeToolkitQt: public CarlaBridgeToolkit,
- public QObject
-{
-public:
- CarlaBridgeToolkitQt(CarlaBridgeClient* const client, const char* const uiTitle)
- : CarlaBridgeToolkit(client, uiTitle),
- QObject(nullptr),
- settings("Cadence", appName)
- {
- qDebug("CarlaBridgeToolkitQt::CarlaBridgeToolkitQt(%p, \"%s\")", client, uiTitle);
-
- app = nullptr;
- window = nullptr;
-
- msgTimer = 0;
-
- needsResize = false;
- nextWidth = 0;
- nextHeight = 0;
-
-#ifdef BRIDGE_CONTAINER
- embedContainer = nullptr;
-#endif
- }
-
- ~CarlaBridgeToolkitQt()
- {
- qDebug("CarlaBridgeToolkitQt::~CarlaBridgeToolkitQt()");
- CARLA_ASSERT(! app);
- CARLA_ASSERT(! window);
- CARLA_ASSERT(! msgTimer);
- }
-
- void init()
- {
- qDebug("CarlaBridgeToolkitQt::init()");
- CARLA_ASSERT(! app);
- CARLA_ASSERT(! window);
- CARLA_ASSERT(! msgTimer);
-
- app = new QApplication(qargc, qargv);
-
- window = new QMainWindow(nullptr);
- window->resize(30, 30);
- window->hide();
- }
-
- void exec(const bool showGui)
- {
- qDebug("CarlaBridgeToolkitQt::exec(%s)", bool2str(showGui));
- CARLA_ASSERT(app);
- CARLA_ASSERT(window);
- CARLA_ASSERT(client);
-
-#if defined(BRIDGE_QT4) || defined(BRIDGE_QT5)
- QWidget* const widget = (QWidget*)client->getWidget();
-
- window->setCentralWidget(widget);
- window->adjustSize();
-
- widget->setParent(window);
- widget->show();
-#endif
-
- if (! client->isResizable())
- {
- window->setFixedSize(window->width(), window->height());
-#ifdef Q_OS_WIN
- window->setWindowFlags(window->windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
-#endif
- }
-
- window->setWindowTitle(uiTitle);
-
- if (settings.contains(QString("%1/pos_x").arg(uiTitle)))
- {
- bool hasX, hasY;
- int posX = settings.value(QString("%1/pos_x").arg(uiTitle), window->x()).toInt(&hasX);
- int posY = settings.value(QString("%1/pos_y").arg(uiTitle), window->y()).toInt(&hasY);
-
- if (hasX && hasY)
- window->move(posX, posY);
-
- if (client->isResizable())
- {
- bool hasWidth, hasHeight;
- int width = settings.value(QString("%1/width").arg(uiTitle), window->width()).toInt(&hasWidth);
- int height = settings.value(QString("%1/height").arg(uiTitle), window->height()).toInt(&hasHeight);
-
- if (hasWidth && hasHeight)
- window->resize(width, height);
- }
- }
-
- if (showGui)
- show();
- else
- client->sendOscUpdate();
-
- // Timer
- msgTimer = startTimer(50);
-
- // First idle
- handleTimeout();
-
- // Main loop
- app->exec();
- }
-
- void quit()
- {
- qDebug("CarlaBridgeToolkitQt::quit()");
- CARLA_ASSERT(app);
-
- if (msgTimer != 0)
- {
- killTimer(msgTimer);
- msgTimer = 0;
- }
-
- if (window)
- {
- settings.setValue(QString("%1/pos_x").arg(uiTitle), window->x());
- settings.setValue(QString("%1/pos_y").arg(uiTitle), window->y());
- settings.setValue(QString("%1/width").arg(uiTitle), window->width());
- settings.setValue(QString("%1/height").arg(uiTitle), window->height());
- settings.sync();
-
- window->close();
-
- delete window;
- window = nullptr;
- }
-
-#ifdef BRIDGE_CONTAINER
- if (embedContainer)
- {
- embedContainer->close();
-
- delete embedContainer;
- embedContainer = nullptr;
- }
-#endif
-
- if (app)
- {
- if (! app->closingDown())
- app->quit();
-
- delete app;
- app = nullptr;
- }
- }
-
- void show()
- {
- qDebug("CarlaBridgeToolkitQt::show()");
- CARLA_ASSERT(window);
-
- if (window)
- window->show();
- }
-
- void hide()
- {
- qDebug("CarlaBridgeToolkitQt::hide()");
- CARLA_ASSERT(window);
-
- if (window)
- window->hide();
- }
-
- void resize(const int width, const int height)
- {
- qDebug("CarlaBridgeToolkitQt::resize(%i, %i)", width, height);
- CARLA_ASSERT(window);
-
- if (app->thread() != QThread::currentThread())
- {
- nextWidth = width;
- nextHeight = height;
- needsResize = true;
- return;
- }
-
- if (window)
- window->setFixedSize(width, height);
-
-#ifdef BRIDGE_CONTAINER
- if (embedContainer)
- embedContainer->setFixedSize(width, height);
-#endif
- }
-
-#ifdef BRIDGE_CONTAINER
- void* getContainerId()
- {
- qDebug("CarlaBridgeToolkitQt::getContainerId()");
- CARLA_ASSERT(window);
-
- if (! embedContainer)
- {
- embedContainer = new QEmbedContainer(window);
-
- window->setCentralWidget(embedContainer);
- window->adjustSize();
-
- embedContainer->setParent(window);
- embedContainer->show();
- }
-
- return (void*)embedContainer->winId();
- }
-#endif
-
-protected:
- QApplication* app;
- QMainWindow* window;
- QSettings settings;
- int msgTimer;
-
- bool needsResize;
- int nextWidth, nextHeight;
-
-#ifdef BRIDGE_CONTAINER
- QEmbedContainer* embedContainer;
-#endif
-
- void handleTimeout()
- {
- if (! client)
- return;
-
- if (needsResize)
- {
- client->toolkitResize(nextWidth, nextHeight);
- needsResize = false;
- }
-
- if (client->isOscControlRegistered() && ! client->oscIdle())
- {
- killTimer(msgTimer);
- msgTimer = 0;
- }
- }
-
-private:
- void timerEvent(QTimerEvent* const event)
- {
- if (event->timerId() == msgTimer)
- handleTimeout();
-
- QObject::timerEvent(event);
- }
-};
-
-// -------------------------------------------------------------------------
-
-CarlaBridgeToolkit* CarlaBridgeToolkit::createNew(CarlaBridgeClient* const client, const char* const uiTitle)
-{
- return new CarlaBridgeToolkitQt(client, uiTitle);
-}
-
-CARLA_BRIDGE_END_NAMESPACE
diff --git a/c++/carla-bridge/carla_bridge_toolkit.cpp b/c++/carla-bridge/carla_bridge_toolkit.cpp
deleted file mode 100644
index 388e916..0000000
--- a/c++/carla-bridge/carla_bridge_toolkit.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Carla Bridge Toolkit
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_bridge_toolkit.hpp"
-#include "carla_utils.hpp"
-
-#include
-#include
-
-CARLA_BRIDGE_START_NAMESPACE
-
-CarlaBridgeToolkit::CarlaBridgeToolkit(CarlaBridgeClient* const client_, const char* const newTitle)
- : client(client_)
-{
- qDebug("CarlaBridgeToolkit::CarlaBridgeToolkit(%p, \"%s\")", client, newTitle);
- CARLA_ASSERT(client);
- CARLA_ASSERT(newTitle);
-
- uiTitle = strdup(newTitle ? newTitle : "(null)");
-}
-
-CarlaBridgeToolkit::~CarlaBridgeToolkit()
-{
- qDebug("CarlaBridgeToolkit::~CarlaBridgeToolkit()");
-
- free(uiTitle);
-}
-
-void* CarlaBridgeToolkit::getContainerId()
-{
- qDebug("CarlaBridgeToolkit::getContainerId()");
- return nullptr;
-}
-
-CARLA_BRIDGE_END_NAMESPACE
diff --git a/c++/carla-bridge/carla_bridge_toolkit.hpp b/c++/carla-bridge/carla_bridge_toolkit.hpp
deleted file mode 100644
index 0f8a9ca..0000000
--- a/c++/carla-bridge/carla_bridge_toolkit.hpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Carla Bridge Toolkit
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_BRIDGE_TOOLKIT_HPP
-#define CARLA_BRIDGE_TOOLKIT_HPP
-
-#include "carla_bridge.hpp"
-
-CARLA_BRIDGE_START_NAMESPACE
-
-#if 0
-} // Fix editor indentation
-#endif
-
-/*!
- * @defgroup CarlaBridgeToolkit Carla Bridge Toolkit
- *
- * The Carla Bridge Toolkit.
- * @{
- */
-
-class CarlaBridgeToolkit
-{
-public:
- CarlaBridgeToolkit(CarlaBridgeClient* const client, const char* const uiTitle);
- virtual ~CarlaBridgeToolkit();
-
- virtual void init() = 0;
- virtual void exec(const bool showGui) = 0;
- virtual void quit() = 0;
-
- virtual void show() = 0;
- virtual void hide() = 0;
- virtual void resize(const int width, const int height) = 0;
-
- virtual void* getContainerId();
-
- static CarlaBridgeToolkit* createNew(CarlaBridgeClient* const client, const char* const uiTitle);
-
-protected:
- CarlaBridgeClient* const client;
- char* uiTitle;
-};
-
-/**@}*/
-
-CARLA_BRIDGE_END_NAMESPACE
-
-#endif // CARLA_BRIDGE_TOOLKIT_HPP
diff --git a/c++/carla-bridge/carla_bridge_ui-lv2.cpp b/c++/carla-bridge/carla_bridge_ui-lv2.cpp
deleted file mode 100644
index 1cad516..0000000
--- a/c++/carla-bridge/carla_bridge_ui-lv2.cpp
+++ /dev/null
@@ -1,1118 +0,0 @@
-/*
- * Carla UI bridge code
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifdef BRIDGE_LV2
-
-#include "carla_bridge_client.hpp"
-#include "carla_lv2_utils.hpp"
-#include "carla_midi.h"
-#include "rtmempool/rtmempool.h"
-
-#include
-#include
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -------------------------------------------------------------------------
-
-// fake values
-uint32_t bufferSize = 512;
-double sampleRate = 44100.0;
-
-// static max values
-const unsigned int MAX_EVENT_BUFFER = 8192; // 0x2000
-
-// feature ids
-const uint32_t lv2_feature_id_bufsize_bounded = 0;
-const uint32_t lv2_feature_id_bufsize_fixed = 1;
-const uint32_t lv2_feature_id_bufsize_powerof2 = 2;
-const uint32_t lv2_feature_id_event = 3;
-const uint32_t lv2_feature_id_logs = 4;
-const uint32_t lv2_feature_id_options = 5;
-const uint32_t lv2_feature_id_programs = 6;
-const uint32_t lv2_feature_id_rtmempool = 7;
-const uint32_t lv2_feature_id_state_make_path = 8;
-const uint32_t lv2_feature_id_state_map_path = 9;
-const uint32_t lv2_feature_id_strict_bounds = 10;
-const uint32_t lv2_feature_id_uri_map = 11;
-const uint32_t lv2_feature_id_urid_map = 12;
-const uint32_t lv2_feature_id_urid_unmap = 13;
-const uint32_t lv2_feature_id_ui_parent = 14;
-const uint32_t lv2_feature_id_ui_port_map = 15;
-const uint32_t lv2_feature_id_ui_resize = 16;
-const uint32_t lv2_feature_count = 17;
-
-// pre-set uri[d] map ids
-const uint32_t CARLA_URI_MAP_ID_NULL = 0;
-const uint32_t CARLA_URI_MAP_ID_ATOM_CHUNK = 1;
-const uint32_t CARLA_URI_MAP_ID_ATOM_DOUBLE = 2;
-const uint32_t CARLA_URI_MAP_ID_ATOM_INT = 3;
-const uint32_t CARLA_URI_MAP_ID_ATOM_PATH = 4;
-const uint32_t CARLA_URI_MAP_ID_ATOM_SEQUENCE = 5;
-const uint32_t CARLA_URI_MAP_ID_ATOM_STRING = 6;
-const uint32_t CARLA_URI_MAP_ID_ATOM_WORKER = 7;
-const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM = 8;
-const uint32_t CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT = 9;
-const uint32_t CARLA_URI_MAP_ID_BUF_MAX_LENGTH = 10;
-const uint32_t CARLA_URI_MAP_ID_BUF_MIN_LENGTH = 11;
-const uint32_t CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE = 12;
-const uint32_t CARLA_URI_MAP_ID_LOG_ERROR = 13;
-const uint32_t CARLA_URI_MAP_ID_LOG_NOTE = 14;
-const uint32_t CARLA_URI_MAP_ID_LOG_TRACE = 15;
-const uint32_t CARLA_URI_MAP_ID_LOG_WARNING = 16;
-const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 17;
-const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 18;
-const uint32_t CARLA_URI_MAP_ID_COUNT = 19;
-
-// -------------------------------------------------------------------------
-
-struct Lv2PluginOptions {
- uint32_t eventSize;
- uint32_t bufferSize;
- double sampleRate;
- LV2_Options_Option oNull;
- LV2_Options_Option oMaxBlockLenth;
- LV2_Options_Option oMinBlockLenth;
- LV2_Options_Option oSequenceSize;
- LV2_Options_Option oSampleRate;
-
- Lv2PluginOptions()
- : eventSize(MAX_EVENT_BUFFER),
- bufferSize(0),
- sampleRate(0.0) {}
-};
-
-Lv2PluginOptions lv2Options;
-
-class CarlaLv2Client : public CarlaBridgeClient
-{
-public:
- CarlaLv2Client(const char* const uiTitle)
- : CarlaBridgeClient(uiTitle)
- {
- handle = nullptr;
- widget = nullptr;
- descriptor = nullptr;
-
- rdf_descriptor = nullptr;
- rdf_ui_descriptor = nullptr;
-
- programs = nullptr;
-
-#ifdef BRIDGE_LV2_X11
- m_resizable = false;
-#else
- m_resizable = true;
-#endif
-
- for (uint32_t i=0; i < CARLA_URI_MAP_ID_COUNT; i++)
- customURIDs.push_back(nullptr);
-
- for (uint32_t i=0; i < lv2_feature_count+1; i++)
- features[i] = nullptr;
-
- // -----------------------------------------------------------------
- // initialize options
-
- lv2Options.bufferSize = bufferSize;
- lv2Options.sampleRate = sampleRate;
-
- lv2Options.oNull.key = CARLA_URI_MAP_ID_NULL;
- lv2Options.oNull.size = 0;
- lv2Options.oNull.type = CARLA_URI_MAP_ID_NULL;
- lv2Options.oNull.value = nullptr;
-
- lv2Options.oMaxBlockLenth.key = CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
- lv2Options.oMaxBlockLenth.size = sizeof(uint32_t);
- lv2Options.oMaxBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
- lv2Options.oMaxBlockLenth.value = &lv2Options.bufferSize;
-
- lv2Options.oMinBlockLenth.key = CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
- lv2Options.oMinBlockLenth.size = sizeof(uint32_t);
- lv2Options.oMinBlockLenth.type = CARLA_URI_MAP_ID_ATOM_INT;
- lv2Options.oMinBlockLenth.value = &lv2Options.bufferSize;
-
- lv2Options.oSequenceSize.key = CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
- lv2Options.oSequenceSize.size = sizeof(uint32_t);
- lv2Options.oSequenceSize.type = CARLA_URI_MAP_ID_ATOM_INT;
- lv2Options.oSequenceSize.value = &lv2Options.eventSize;
-
- lv2Options.oSampleRate.key = CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
- lv2Options.oSampleRate.size = sizeof(double);
- lv2Options.oSampleRate.type = CARLA_URI_MAP_ID_ATOM_DOUBLE;
- lv2Options.oSampleRate.value = &lv2Options.sampleRate;
-
- // -----------------------------------------------------------------
- // initialize features
-
- LV2_Event_Feature* const eventFt = new LV2_Event_Feature;
- eventFt->callback_data = this;
- eventFt->lv2_event_ref = carla_lv2_event_ref;
- eventFt->lv2_event_unref = carla_lv2_event_unref;
-
- LV2_Log_Log* const logFt = new LV2_Log_Log;
- logFt->handle = this;
- logFt->printf = carla_lv2_log_printf;
- logFt->vprintf = carla_lv2_log_vprintf;
-
- LV2_Programs_Host* const programsFt = new LV2_Programs_Host;
- programsFt->handle = this;
- programsFt->program_changed = carla_lv2_program_changed;
-
- LV2_RtMemPool_Pool* const rtMemPoolFt = new LV2_RtMemPool_Pool;
- rtmempool_allocator_init(rtMemPoolFt);
-
- LV2_State_Make_Path* const stateMakePathFt = new LV2_State_Make_Path;
- stateMakePathFt->handle = this;
- stateMakePathFt->path = carla_lv2_state_make_path;
-
- LV2_State_Map_Path* const stateMapPathFt = new LV2_State_Map_Path;
- stateMapPathFt->handle = this;
- stateMapPathFt->abstract_path = carla_lv2_state_map_abstract_path;
- stateMapPathFt->absolute_path = carla_lv2_state_map_absolute_path;
-
- LV2_URI_Map_Feature* const uriMapFt = new LV2_URI_Map_Feature;
- uriMapFt->callback_data = this;
- uriMapFt->uri_to_id = carla_lv2_uri_to_id;
-
- LV2_URID_Map* const uridMapFt = new LV2_URID_Map;
- uridMapFt->handle = this;
- uridMapFt->map = carla_lv2_urid_map;
-
- LV2_URID_Unmap* const uridUnmapFt = new LV2_URID_Unmap;
- uridUnmapFt->handle = this;
- uridUnmapFt->unmap = carla_lv2_urid_unmap;
-
- LV2UI_Port_Map* const uiPortMapFt = new LV2UI_Port_Map;
- uiPortMapFt->handle = this;
- uiPortMapFt->port_index = carla_lv2_ui_port_map;
-
- LV2UI_Resize* const uiResizeFt = new LV2UI_Resize;
- uiResizeFt->handle = this;
- uiResizeFt->ui_resize = carla_lv2_ui_resize;
-
- LV2_Options_Option* const optionsFt = new LV2_Options_Option [5];
- optionsFt[0] = lv2Options.oMaxBlockLenth;
- optionsFt[1] = lv2Options.oMinBlockLenth;
- optionsFt[2] = lv2Options.oSequenceSize;
- optionsFt[3] = lv2Options.oSampleRate;
- optionsFt[4] = lv2Options.oNull;
-
- features[lv2_feature_id_bufsize_bounded] = new LV2_Feature;
- features[lv2_feature_id_bufsize_bounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
- features[lv2_feature_id_bufsize_bounded]->data = nullptr;
-
- features[lv2_feature_id_bufsize_fixed] = new LV2_Feature;
- features[lv2_feature_id_bufsize_fixed]->URI = LV2_BUF_SIZE__fixedBlockLength;
- features[lv2_feature_id_bufsize_fixed]->data = nullptr;
-
- features[lv2_feature_id_bufsize_powerof2] = new LV2_Feature;
- features[lv2_feature_id_bufsize_powerof2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
- features[lv2_feature_id_bufsize_powerof2]->data = nullptr;
-
- features[lv2_feature_id_event] = new LV2_Feature;
- features[lv2_feature_id_event]->URI = LV2_EVENT_URI;
- features[lv2_feature_id_event]->data = eventFt;
-
- features[lv2_feature_id_logs] = new LV2_Feature;
- features[lv2_feature_id_logs]->URI = LV2_LOG__log;
- features[lv2_feature_id_logs]->data = logFt;
-
- features[lv2_feature_id_options] = new LV2_Feature;
- features[lv2_feature_id_options]->URI = LV2_OPTIONS__options;
- features[lv2_feature_id_options]->data = optionsFt;
-
- features[lv2_feature_id_programs] = new LV2_Feature;
- features[lv2_feature_id_programs]->URI = LV2_PROGRAMS__Host;
- features[lv2_feature_id_programs]->data = programsFt;
-
- features[lv2_feature_id_rtmempool] = new LV2_Feature;
- features[lv2_feature_id_rtmempool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
- features[lv2_feature_id_rtmempool]->data = rtMemPoolFt;
-
- features[lv2_feature_id_state_make_path] = new LV2_Feature;
- features[lv2_feature_id_state_make_path]->URI = LV2_STATE__makePath;
- features[lv2_feature_id_state_make_path]->data = stateMakePathFt;
-
- features[lv2_feature_id_state_map_path] = new LV2_Feature;
- features[lv2_feature_id_state_map_path]->URI = LV2_STATE__mapPath;
- features[lv2_feature_id_state_map_path]->data = stateMapPathFt;
-
- features[lv2_feature_id_strict_bounds] = new LV2_Feature;
- features[lv2_feature_id_strict_bounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
- features[lv2_feature_id_strict_bounds]->data = nullptr;
-
- features[lv2_feature_id_uri_map] = new LV2_Feature;
- features[lv2_feature_id_uri_map]->URI = LV2_URI_MAP_URI;
- features[lv2_feature_id_uri_map]->data = uriMapFt;
-
- features[lv2_feature_id_urid_map] = new LV2_Feature;
- features[lv2_feature_id_urid_map]->URI = LV2_URID__map;
- features[lv2_feature_id_urid_map]->data = uridMapFt;
-
- features[lv2_feature_id_urid_unmap] = new LV2_Feature;
- features[lv2_feature_id_urid_unmap]->URI = LV2_URID__unmap;
- features[lv2_feature_id_urid_unmap]->data = uridUnmapFt;
-
- features[lv2_feature_id_ui_parent] = new LV2_Feature;
- features[lv2_feature_id_ui_parent]->URI = LV2_UI__parent;
-#ifdef BRIDGE_LV2_X11
- features[lv2_feature_id_ui_parent]->data = getContainerId();
-#else
- features[lv2_feature_id_ui_parent]->data = nullptr;
-#endif
-
- features[lv2_feature_id_ui_port_map] = new LV2_Feature;
- features[lv2_feature_id_ui_port_map]->URI = LV2_UI__portMap;
- features[lv2_feature_id_ui_port_map]->data = uiPortMapFt;
-
- features[lv2_feature_id_ui_resize] = new LV2_Feature;
- features[lv2_feature_id_ui_resize]->URI = LV2_UI__resize;
- features[lv2_feature_id_ui_resize]->data = uiResizeFt;
- }
-
- ~CarlaLv2Client()
- {
- if (rdf_descriptor)
- delete rdf_descriptor;
-
- const LV2_Options_Option* const options = (const LV2_Options_Option*)features[lv2_feature_id_options]->data;
- delete[] options;
-
- delete (LV2_Event_Feature*)features[lv2_feature_id_event]->data;
- delete (LV2_Log_Log*)features[lv2_feature_id_logs]->data;
- delete (LV2_Programs_Host*)features[lv2_feature_id_programs]->data;
- delete (LV2_RtMemPool_Pool*)features[lv2_feature_id_rtmempool]->data;
- delete (LV2_State_Make_Path*)features[lv2_feature_id_state_make_path]->data;
- delete (LV2_State_Map_Path*)features[lv2_feature_id_state_map_path]->data;
- delete (LV2_URI_Map_Feature*)features[lv2_feature_id_uri_map]->data;
- delete (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
- delete (LV2_URID_Unmap*)features[lv2_feature_id_urid_unmap]->data;
- delete (LV2UI_Port_Map*)features[lv2_feature_id_ui_port_map]->data;
- delete (LV2UI_Resize*)features[lv2_feature_id_ui_resize]->data;
-
- for (uint32_t i=0; i < lv2_feature_count; i++)
- {
- if (features[i])
- delete features[i];
- }
-
- for (size_t i=0; i < customURIDs.size(); i++)
- {
- if (customURIDs[i])
- free((void*)customURIDs[i]);
- }
-
- customURIDs.clear();
- }
-
- // ---------------------------------------------------------------------
- // ui initialization
-
- bool init(const char* pluginURI, const char* uiURI)
- {
- // -----------------------------------------------------------------
- // init
-
- CarlaBridgeClient::init(pluginURI, uiURI);
-
- // -----------------------------------------------------------------
- // get plugin from lv2_rdf (lilv)
-
- lv2World.init();
- rdf_descriptor = lv2_rdf_new(pluginURI);
-
- if (! rdf_descriptor)
- return false;
-
- // -----------------------------------------------------------------
- // find requested UI
-
- for (uint32_t i=0; i < rdf_descriptor->UICount; i++)
- {
- if (strcmp(rdf_descriptor->UIs[i].URI, uiURI) == 0)
- {
- rdf_ui_descriptor = &rdf_descriptor->UIs[i];
- break;
- }
- }
-
- if (! rdf_ui_descriptor)
- return false;
-
- // -----------------------------------------------------------------
- // open DLL
-
- if (! uiLibOpen(rdf_ui_descriptor->Binary))
- return false;
-
- // -----------------------------------------------------------------
- // get DLL main entry
-
- const LV2UI_DescriptorFunction ui_descFn = (LV2UI_DescriptorFunction)uiLibSymbol("lv2ui_descriptor");
-
- if (! ui_descFn)
- return false;
-
- // -----------------------------------------------------------
- // get descriptor that matches URI
-
- uint32_t i = 0;
- while ((descriptor = ui_descFn(i++)))
- {
- if (strcmp(descriptor->URI, uiURI) == 0)
- break;
- }
-
- if (! descriptor)
- return false;
-
- // -----------------------------------------------------------
- // initialize UI
-
- handle = descriptor->instantiate(descriptor, pluginURI, rdf_ui_descriptor->Bundle, carla_lv2_ui_write_function, this, &widget, features);
-
- if (! handle)
- return false;
-
- // -----------------------------------------------------------
- // check if not resizable
-
-#ifndef BRIDGE_LV2_X11
- for (uint32_t i=0; i < rdf_ui_descriptor->FeatureCount; i++)
- {
- if (strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__fixedSize) == 0 || strcmp(rdf_ui_descriptor->Features[i].URI, LV2_UI__noUserResize) == 0)
- {
- m_resizable = false;
- break;
- }
- }
-#endif
-
- // -----------------------------------------------------------
- // check for known extensions
-
- for (uint32_t i=0; descriptor->extension_data && i < rdf_ui_descriptor->ExtensionCount; i++)
- {
- if (strcmp(rdf_ui_descriptor->Extensions[i], LV2_PROGRAMS__UIInterface) == 0)
- {
- programs = (LV2_Programs_UI_Interface*)descriptor->extension_data(LV2_PROGRAMS__UIInterface);
-
- if (programs && ! programs->select_program)
- // invalid
- programs = nullptr;
-
- break;
- }
- }
-
- return true;
- }
-
- void close()
- {
- CarlaBridgeClient::close();
-
- if (handle && descriptor && descriptor->cleanup)
- descriptor->cleanup(handle);
-
- uiLibClose();
- }
-
- // ---------------------------------------------------------------------
- // ui management
-
- void* getWidget() const
- {
- return widget;
- }
-
- bool isResizable() const
- {
- return m_resizable;
- }
-
- bool needsReparent() const
- {
-#ifdef BRIDGE_LV2_X11
- return true;
-#else
- return false;
-#endif
- }
-
- // ---------------------------------------------------------------------
- // processing
-
- void setParameter(const int32_t rindex, const double value)
- {
- CARLA_ASSERT(handle && descriptor);
-
- if (handle && descriptor && descriptor->port_event)
- {
- float fvalue = value;
- descriptor->port_event(handle, rindex, sizeof(float), 0, &fvalue);
- }
- }
-
- void setProgram(const uint32_t)
- {
- }
-
- void setMidiProgram(const uint32_t bank, const uint32_t program)
- {
- CARLA_ASSERT(handle);
-
- if (handle && programs)
- programs->select_program(handle, bank, program);
- }
-
- void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo)
- {
- CARLA_ASSERT(handle && descriptor);
-
- if (handle && descriptor && descriptor->port_event)
- {
- LV2_Atom_MidiEvent midiEv;
- midiEv.event.time.frames = 0;
- midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
- midiEv.event.body.size = 3;
- midiEv.data[0] = MIDI_STATUS_NOTE_ON + channel;
- midiEv.data[1] = note;
- midiEv.data[2] = velo;
-
- descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
- }
- }
-
- void noteOff(const uint8_t channel, const uint8_t note)
- {
- CARLA_ASSERT(handle && descriptor);
-
- if (handle && descriptor && descriptor->port_event)
- {
- LV2_Atom_MidiEvent midiEv;
- midiEv.event.time.frames = 0;
- midiEv.event.body.type = CARLA_URI_MAP_ID_MIDI_EVENT;
- midiEv.event.body.size = 3;
- midiEv.data[0] = MIDI_STATUS_NOTE_OFF + channel;
- midiEv.data[1] = note;
- midiEv.data[2] = 0;
-
- descriptor->port_event(handle, 0, 3, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, &midiEv);
- }
- }
-
- // ---------------------------------------------------------------------
-
- uint32_t getCustomURID(const char* const uri)
- {
- qDebug("CarlaLv2Client::getCustomURID(%s)", uri);
- CARLA_ASSERT(uri);
-
- if (! uri)
- return CARLA_URI_MAP_ID_NULL;
-
- for (size_t i=0; i < customURIDs.size(); i++)
- {
- if (customURIDs[i] && strcmp(customURIDs[i], uri) == 0)
- return i;
- }
-
- customURIDs.push_back(strdup(uri));
-
- return customURIDs.size()-1;
- }
-
- const char* getCustomURIString(const LV2_URID urid) const
- {
- qDebug("CarlaLv2Client::getCustomURIString(%i)", urid);
- CARLA_ASSERT(urid > CARLA_URI_MAP_ID_NULL);
-
- if (urid == CARLA_URI_MAP_ID_NULL)
- return nullptr;
- if (urid < customURIDs.size())
- return customURIDs[urid];
-
- return nullptr;
- }
-
- // ---------------------------------------------------------------------
-
- void handleTransferAtom(const int32_t portIndex, const LV2_Atom* const atom)
- {
- qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
- CARLA_ASSERT(portIndex >= 0);
- CARLA_ASSERT(atom);
-
- if (atom && handle && descriptor && descriptor->port_event)
- descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM, atom);
- }
-
- void handleTransferEvent(const int32_t portIndex, const LV2_Atom* const atom)
- {
- qDebug("CarlaLv2Client::handleTransferEvent(%i, %p)", portIndex, atom);
- CARLA_ASSERT(portIndex >= 0);
- CARLA_ASSERT(atom);
-
- if (atom && handle && descriptor && descriptor->port_event)
- descriptor->port_event(handle, portIndex, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
-#if 0
- if (handle && descriptor && descriptor->port_event)
- {
- LV2_URID_Map* const URID_Map = (LV2_URID_Map*)features[lv2_feature_id_urid_map]->data;
- const LV2_URID uridPatchSet = getCustomURID(LV2_PATCH__Set);
- const LV2_URID uridPatchBody = getCustomURID(LV2_PATCH__body);
-
- Sratom* sratom = sratom_new(URID_Map);
- SerdChunk chunk = { nullptr, 0 };
-
- LV2_Atom_Forge forge;
- lv2_atom_forge_init(&forge, URID_Map);
- lv2_atom_forge_set_sink(&forge, sratom_forge_sink, sratom_forge_deref, &chunk);
-
- LV2_Atom_Forge_Frame refFrame, bodyFrame;
- LV2_Atom_Forge_Ref ref = lv2_atom_forge_blank(&forge, &refFrame, 1, uridPatchSet);
-
- lv2_atom_forge_property_head(&forge, uridPatchBody, CARLA_URI_MAP_ID_NULL);
- lv2_atom_forge_blank(&forge, &bodyFrame, 2, CARLA_URI_MAP_ID_NULL);
-
- //lv2_atom_forge_property_head(&forge, getCustomURID(key), CARLA_URI_MAP_ID_NULL);
-
- if (strcmp(type, "string") == 0)
- lv2_atom_forge_string(&forge, value, strlen(value));
- else if (strcmp(type, "path") == 0)
- lv2_atom_forge_path(&forge, value, strlen(value));
- else if (strcmp(type, "chunk") == 0)
- lv2_atom_forge_literal(&forge, value, strlen(value), CARLA_URI_MAP_ID_ATOM_CHUNK, CARLA_URI_MAP_ID_NULL);
- //else
- // lv2_atom_forge_literal(&forge, value, strlen(value), getCustomURID(key), CARLA_URI_MAP_ID_NULL);
-
- lv2_atom_forge_pop(&forge, &bodyFrame);
- lv2_atom_forge_pop(&forge, &refFrame);
-
- const LV2_Atom* const atom = lv2_atom_forge_deref(&forge, ref);
- descriptor->port_event(handle, 0, atom->size, CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT, atom);
-
- free((void*)chunk.buf);
- sratom_free(sratom);
- }
-#endif
- }
-
- // ---------------------------------------------------------------------
-
- void handleProgramChanged(int32_t /*index*/)
- {
- if (isOscControlRegistered())
- sendOscConfigure("reloadprograms", "");
- }
-
- uint32_t handleUiPortMap(const char* const symbol)
- {
- CARLA_ASSERT(symbol);
-
- if (! symbol)
- return LV2UI_INVALID_PORT_INDEX;
-
- for (uint32_t i=0; i < rdf_descriptor->PortCount; i++)
- {
- if (strcmp(rdf_descriptor->Ports[i].Symbol, symbol) == 0)
- return i;
- }
-
- return LV2UI_INVALID_PORT_INDEX;
- }
-
-
- int handleUiResize(int width, int height)
- {
- CARLA_ASSERT(width > 0);
- CARLA_ASSERT(height > 0);
-
- if (width <= 0 || height <= 0)
- return 1;
-
- toolkitResize(width, height);
-
- return 0;
- }
-
- void handleUiWrite(uint32_t portIndex, uint32_t bufferSize, uint32_t format, const void* buffer)
- {
- if (! (buffer && isOscControlRegistered()))
- return;
-
- if (format == 0)
- {
- CARLA_ASSERT(buffer);
- CARLA_ASSERT(bufferSize == sizeof(float));
-
- if (bufferSize != sizeof(float))
- return;
-
- float value = *(float*)buffer;
- sendOscControl(portIndex, value);
- }
- else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
- {
- CARLA_ASSERT(buffer);
- const LV2_Atom* const atom = (const LV2_Atom*)buffer;
-
- QByteArray chunk((const char*)buffer, bufferSize);
- sendOscLv2TransferAtom(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
- }
- else if (format == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
- {
- CARLA_ASSERT(buffer);
- const LV2_Atom* const atom = (const LV2_Atom*)buffer;
-
- QByteArray chunk((const char*)buffer, bufferSize);
- sendOscLv2TransferEvent(portIndex, getCustomURIString(atom->type), chunk.toBase64().constData());
- }
- }
-
- // ----------------- Event Feature ---------------------------------------------------
-
- static uint32_t carla_lv2_event_ref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
- {
- qDebug("CarlaLv2Client::carla_lv2_event_ref(%p, %p)", callback_data, event);
- CARLA_ASSERT(callback_data);
- CARLA_ASSERT(event);
-
- return 0;
- }
-
- static uint32_t carla_lv2_event_unref(const LV2_Event_Callback_Data callback_data, LV2_Event* const event)
- {
- qDebug("CarlaLv2Client::carla_lv2_event_unref(%p, %p)", callback_data, event);
- CARLA_ASSERT(callback_data);
- CARLA_ASSERT(event);
-
- return 0;
- }
-
- // ----------------- Logs Feature ----------------------------------------------------
-
- static int carla_lv2_log_printf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, ...)
- {
- qDebug("CarlaLv2Client::carla_lv2_log_printf(%p, %i, %s, ...)", handle, type, fmt);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(type > 0);
-
-#ifndef DEBUG
- if (type == CARLA_URI_MAP_ID_LOG_TRACE)
- return 0;
-#endif
-
- va_list args;
- va_start(args, fmt);
- const int ret = carla_lv2_log_vprintf(handle, type, fmt, args);
- va_end(args);
-
- return ret;
- }
-
- static int carla_lv2_log_vprintf(const LV2_Log_Handle handle, const LV2_URID type, const char* const fmt, va_list ap)
- {
- qDebug("CarlaLv2Client::carla_lv2_log_vprintf(%p, %i, %s, ...)", handle, type, fmt);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(type > 0);
-
-#ifndef DEBUG
- if (type == CARLA_URI_MAP_ID_LOG_TRACE)
- return 0;
-#endif
-
- char buf[8196];
- vsprintf(buf, fmt, ap);
-
- if (*buf == 0)
- return 0;
-
- switch (type)
- {
- case CARLA_URI_MAP_ID_LOG_ERROR:
- qCritical("%s", buf);
- break;
- case CARLA_URI_MAP_ID_LOG_NOTE:
- printf("%s\n", buf);
- break;
- case CARLA_URI_MAP_ID_LOG_TRACE:
- qDebug("%s", buf);
- break;
- case CARLA_URI_MAP_ID_LOG_WARNING:
- qWarning("%s", buf);
- break;
- default:
- break;
- }
-
- return strlen(buf);
- }
-
- // ----------------- Programs Feature ------------------------------------------------
-
- static void carla_lv2_program_changed(const LV2_Programs_Handle handle, const int32_t index)
- {
- qDebug("CarlaLv2Client::carla_lv2_program_changed(%p, %i)", handle, index);
- CARLA_ASSERT(handle);
-
- if (! handle)
- return;
-
- CarlaLv2Client* const client = (CarlaLv2Client*)handle;
- client->handleProgramChanged(index);
- }
-
- // ----------------- State Feature ---------------------------------------------------
-
- static char* carla_lv2_state_make_path(const LV2_State_Make_Path_Handle handle, const char* const path)
- {
- qDebug("CarlaLv2Client::carla_lv2_state_make_path(%p, %p)", handle, path);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(path);
-
- if (! path)
- return nullptr;
-
- QDir dir;
- dir.mkpath(path);
- return strdup(path);
- }
-
- static char* carla_lv2_state_map_abstract_path(const LV2_State_Map_Path_Handle handle, const char* const absolute_path)
- {
- qDebug("CarlaLv2Client::carla_lv2_state_map_abstract_path(%p, %p)", handle, absolute_path);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(absolute_path);
-
- if (! absolute_path)
- return nullptr;
-
- QDir dir(absolute_path);
- return strdup(dir.canonicalPath().toUtf8().constData());
- }
-
- static char* carla_lv2_state_map_absolute_path(const LV2_State_Map_Path_Handle handle, const char* const abstract_path)
- {
- qDebug("CarlaLv2Client::carla_lv2_state_map_absolute_path(%p, %p)", handle, abstract_path);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(abstract_path);
-
- if (! abstract_path)
- return nullptr;
-
- QDir dir(abstract_path);
- return strdup(dir.absolutePath().toUtf8().constData());
- }
-
- // ----------------- URI-Map Feature ---------------------------------------
-
- static uint32_t carla_lv2_uri_to_id(const LV2_URI_Map_Callback_Data data, const char* const map, const char* const uri)
- {
- qDebug("CarlaLv2Client::carla_lv2_uri_to_id(%p, %s, %s)", data, map, uri);
- return carla_lv2_urid_map((LV2_URID_Map_Handle*)data, uri);
- }
-
- // ----------------- URID Feature ------------------------------------------
-
- static LV2_URID carla_lv2_urid_map(const LV2_URID_Map_Handle handle, const char* const uri)
- {
- qDebug("CarlaLv2Client::carla_lv2_urid_map(%p, %s)", handle, uri);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(uri);
-
- if (! uri)
- return CARLA_URI_MAP_ID_NULL;
-
- // Atom types
- if (strcmp(uri, LV2_ATOM__Chunk) == 0)
- return CARLA_URI_MAP_ID_ATOM_CHUNK;
- if (strcmp(uri, LV2_ATOM__Double) == 0)
- return CARLA_URI_MAP_ID_ATOM_DOUBLE;
- if (strcmp(uri, LV2_ATOM__Int) == 0)
- return CARLA_URI_MAP_ID_ATOM_INT;
- if (strcmp(uri, LV2_ATOM__Path) == 0)
- return CARLA_URI_MAP_ID_ATOM_PATH;
- if (strcmp(uri, LV2_ATOM__Sequence) == 0)
- return CARLA_URI_MAP_ID_ATOM_SEQUENCE;
- if (strcmp(uri, LV2_ATOM__String) == 0)
- return CARLA_URI_MAP_ID_ATOM_STRING;
- if (strcmp(uri, LV2_ATOM__atomTransfer) == 0)
- return CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM;
- if (strcmp(uri, LV2_ATOM__eventTransfer) == 0)
- return CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT;
-
- // BufSize types
- if (strcmp(uri, LV2_BUF_SIZE__maxBlockLength) == 0)
- return CARLA_URI_MAP_ID_BUF_MAX_LENGTH;
- if (strcmp(uri, LV2_BUF_SIZE__minBlockLength) == 0)
- return CARLA_URI_MAP_ID_BUF_MIN_LENGTH;
- if (strcmp(uri, LV2_BUF_SIZE__sequenceSize) == 0)
- return CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE;
-
- // Log types
- if (strcmp(uri, LV2_LOG__Error) == 0)
- return CARLA_URI_MAP_ID_LOG_ERROR;
- if (strcmp(uri, LV2_LOG__Note) == 0)
- return CARLA_URI_MAP_ID_LOG_NOTE;
- if (strcmp(uri, LV2_LOG__Trace) == 0)
- return CARLA_URI_MAP_ID_LOG_TRACE;
- if (strcmp(uri, LV2_LOG__Warning) == 0)
- return CARLA_URI_MAP_ID_LOG_WARNING;
-
- // Others
- if (strcmp(uri, LV2_MIDI__MidiEvent) == 0)
- return CARLA_URI_MAP_ID_MIDI_EVENT;
- if (strcmp(uri, LV2_PARAMETERS__sampleRate) == 0)
- return CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE;
-
- if (! handle)
- return CARLA_URI_MAP_ID_NULL;
-
- // Custom types
- CarlaLv2Client* const client = (CarlaLv2Client*)handle;
- return client->getCustomURID(uri);
- }
-
- static const char* carla_lv2_urid_unmap(const LV2_URID_Map_Handle handle, const LV2_URID urid)
- {
- qDebug("CarlaLv2Client::carla_lv2_urid_unmap(%p, %i)", handle, urid);
- CARLA_ASSERT(handle);
- CARLA_ASSERT(urid > CARLA_URI_MAP_ID_NULL);
-
- if (urid == CARLA_URI_MAP_ID_NULL)
- return nullptr;
-
- // Atom types
- if (urid == CARLA_URI_MAP_ID_ATOM_CHUNK)
- return LV2_ATOM__Chunk;
- if (urid == CARLA_URI_MAP_ID_ATOM_DOUBLE)
- return LV2_ATOM__Double;
- if (urid == CARLA_URI_MAP_ID_ATOM_INT)
- return LV2_ATOM__Int;
- if (urid == CARLA_URI_MAP_ID_ATOM_PATH)
- return LV2_ATOM__Path;
- if (urid == CARLA_URI_MAP_ID_ATOM_SEQUENCE)
- return LV2_ATOM__Sequence;
- if (urid == CARLA_URI_MAP_ID_ATOM_STRING)
- return LV2_ATOM__String;
- if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_ATOM)
- return LV2_ATOM__atomTransfer;
- if (urid == CARLA_URI_MAP_ID_ATOM_TRANSFER_EVENT)
- return LV2_ATOM__eventTransfer;
-
- // BufSize types
- if (urid == CARLA_URI_MAP_ID_BUF_MAX_LENGTH)
- return LV2_BUF_SIZE__maxBlockLength;
- if (urid == CARLA_URI_MAP_ID_BUF_MIN_LENGTH)
- return LV2_BUF_SIZE__minBlockLength;
- if (urid == CARLA_URI_MAP_ID_BUF_SEQUENCE_SIZE)
- return LV2_BUF_SIZE__sequenceSize;
-
- // Log types
- if (urid == CARLA_URI_MAP_ID_LOG_ERROR)
- return LV2_LOG__Error;
- if (urid == CARLA_URI_MAP_ID_LOG_NOTE)
- return LV2_LOG__Note;
- if (urid == CARLA_URI_MAP_ID_LOG_TRACE)
- return LV2_LOG__Trace;
- if (urid == CARLA_URI_MAP_ID_LOG_WARNING)
- return LV2_LOG__Warning;
-
- // Others
- if (urid == CARLA_URI_MAP_ID_MIDI_EVENT)
- return LV2_MIDI__MidiEvent;
- if (urid == CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE)
- return LV2_PARAMETERS__sampleRate;
-
- if (! handle)
- return nullptr;
-
- // Custom types
- CarlaLv2Client* const client = (CarlaLv2Client*)handle;
- return client->getCustomURIString(urid);
- }
-
- // ----------------- UI Port-Map Feature ---------------------------------------------
-
- static uint32_t carla_lv2_ui_port_map(const LV2UI_Feature_Handle handle, const char* const symbol)
- {
- qDebug("CarlaLv2Client::carla_lv2_ui_port_map(%p, %s)", handle, symbol);
- CARLA_ASSERT(handle);
-
- if (! handle)
- return LV2UI_INVALID_PORT_INDEX;
-
- CarlaLv2Client* const client = (CarlaLv2Client*)handle;
- return client->handleUiPortMap(symbol);
- }
-
-
- // ----------------- UI Resize Feature -------------------------------------
-
- static int carla_lv2_ui_resize(const LV2UI_Feature_Handle handle, const int width, const int height)
- {
- qDebug("CarlaLv2Client::carla_lv2_ui_resize(%p, %i, %i)", handle, width, height);
- CARLA_ASSERT(handle);
-
- if (! handle)
- return 1;
-
- CarlaLv2Client* const client = (CarlaLv2Client*)handle;
- return client->handleUiResize(width, height);
- }
-
- // ----------------- UI Extension ------------------------------------------
-
- static void carla_lv2_ui_write_function(const LV2UI_Controller controller, const uint32_t port_index, const uint32_t buffer_size, const uint32_t format, const void* const buffer)
- {
- qDebug("CarlaLv2Client::carla_lv2_ui_write_function(%p, %i, %i, %i, %p)", controller, port_index, buffer_size, format, buffer);
- CARLA_ASSERT(controller);
-
- if (! controller)
- return;
-
- CarlaLv2Client* const client = (CarlaLv2Client*)controller;
- client->handleUiWrite(port_index, buffer_size, format, buffer);
- }
-
-private:
- LV2UI_Handle handle;
- LV2UI_Widget widget;
- const LV2UI_Descriptor* descriptor;
- LV2_Feature* features[lv2_feature_count+1];
-
- const LV2_RDF_Descriptor* rdf_descriptor;
- const LV2_RDF_UI* rdf_ui_descriptor;
-
- const LV2_Programs_UI_Interface* programs;
-
- bool m_resizable;
- std::vector customURIDs;
-};
-
-int CarlaBridgeOsc::handleMsgLv2TransferAtom(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgLv2TransferAtom()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");
-
- if (! client)
- return 1;
-
- const int32_t portIndex = argv[0]->i;
- const char* const typeStr = (const char*)&argv[1]->s;
- const char* const atomBuf = (const char*)&argv[2]->s;
-
- QByteArray chunk;
- chunk = QByteArray::fromBase64(atomBuf);
-
- LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
- CarlaLv2Client* const lv2Client = (CarlaLv2Client*)client;
-
- atom->type = lv2Client->getCustomURID(typeStr);
- lv2Client->handleTransferAtom(portIndex, atom);
-
- return 0;
-}
-
-int CarlaBridgeOsc::handleMsgLv2TransferEvent(CARLA_BRIDGE_OSC_HANDLE_ARGS)
-{
- qDebug("CarlaBridgeOsc::handleMsgLv2TransferEvent()");
- CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "iss");
-
- if (! client)
- return 1;
-
- const int32_t portIndex = argv[0]->i;
- const char* const typeStr = (const char*)&argv[1]->s;
- const char* const atomBuf = (const char*)&argv[2]->s;
-
- QByteArray chunk;
- chunk = QByteArray::fromBase64(atomBuf);
-
- LV2_Atom* const atom = (LV2_Atom*)chunk.constData();
- CarlaLv2Client* const lv2Client = (CarlaLv2Client*)client;
-
- atom->type = lv2Client->getCustomURID(typeStr);
- lv2Client->handleTransferEvent(portIndex, atom);
-
- return 0;
-}
-
-CARLA_BRIDGE_END_NAMESPACE
-
-int main(int argc, char* argv[])
-{
- CARLA_BRIDGE_USE_NAMESPACE
-
- if (argc != 5)
- {
- qWarning("usage: %s ", argv[0]);
- return 1;
- }
-
- const char* oscUrl = argv[1];
- const char* pluginURI = argv[2];
- const char* uiURI = argv[3];
- const char* uiTitle = argv[4];
-
- const bool useOsc = strcmp(oscUrl, "null");
-
- // try to get sampleRate value
- const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE");
-
- if (sampleRateStr)
- sampleRate = atof(sampleRateStr);
-
- // Init LV2 client
- CarlaLv2Client client(uiTitle);
-
- // Init OSC
- if (useOsc && ! client.oscInit(oscUrl))
- {
- return -1;
- }
-
- // Load UI
- int ret;
-
- if (client.init(pluginURI, uiURI))
- {
- client.toolkitExec(!useOsc);
- ret = 0;
- }
- else
- {
- qCritical("Failed to load LV2 UI");
- ret = 1;
- }
-
- // Close OSC
- if (useOsc)
- {
- client.oscClose();
- }
-
- // Close LV2 client
- client.close();
-
- return ret;
-}
-
-#endif // BRIDGE_LV2
diff --git a/c++/carla-bridge/carla_bridge_ui-vst.cpp b/c++/carla-bridge/carla_bridge_ui-vst.cpp
deleted file mode 100644
index 660aa1a..0000000
--- a/c++/carla-bridge/carla_bridge_ui-vst.cpp
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Carla Bridge UI, VST version
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifdef BRIDGE_VST
-
-#include "carla_bridge_client.hpp"
-#include "carla_bridge_toolkit.hpp"
-#include "carla_vst_utils.hpp"
-#include "carla_midi.h"
-
-#include
-#include
-
-#if defined(Q_WS_X11) && (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
-# include
-#endif
-
-CARLA_BRIDGE_START_NAMESPACE
-
-// -------------------------------------------------------------------------
-
-// fake values
-uint32_t bufferSize = 512;
-double sampleRate = 44100.0;
-
-class CarlaVstClient : public CarlaBridgeClient,
- public QObject
-{
-public:
- CarlaVstClient(const char* const uiTitle)
- : CarlaBridgeClient(uiTitle),
- QObject(nullptr)
- {
- effect = nullptr;
-
- idleTimer = 0;
- needIdle = false;
-
- // make client valid
- srand(uiTitle[0]);
- unique1 = unique2 = rand();
- }
-
- ~CarlaVstClient()
- {
- // make client invalid
- unique2 += 1;
- }
-
- // ---------------------------------------------------------------------
- // ui initialization
-
- bool init(const char* binary, const char*)
- {
- // -----------------------------------------------------------------
- // init
-
- CarlaBridgeClient::init(binary, nullptr);
-
- // -----------------------------------------------------------------
- // open DLL
-
- if (! uiLibOpen(binary))
- {
- qWarning("%s", uiLibError());
- return false;
- }
-
- // -----------------------------------------------------------------
- // get DLL main entry
-
- VST_Function vstFn = (VST_Function)uiLibSymbol("VSTPluginMain");
-
- if (! vstFn)
- vstFn = (VST_Function)uiLibSymbol("main");
-
- if (! vstFn)
- return false;
-
- // -----------------------------------------------------------------
- // initialize plugin
-
- lastVstPlugin = this;
- effect = vstFn(hostCallback);
- lastVstPlugin = nullptr;
-
- if (! (effect && effect->magic == kEffectMagic))
- return false;
-
- // -----------------------------------------------------------------
- // initialize VST stuff
-
-#ifdef VESTIGE_HEADER
- effect->ptr1 = this;
-#else
- effect->resvd1 = ToVstPtr(this);
-#endif
-
- int32_t value = 0;
-#if defined(Q_WS_X11) && (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
- value = (int64_t)QX11Info::display();
-#endif
-
- effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
- effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
-
-#if ! VST_FORCE_DEPRECATED
- effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, bufferSize, nullptr, sampleRate);
-#endif
- effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, sampleRate);
- effect->dispatcher(effect, effSetBlockSize, 0, bufferSize, nullptr, 0.0f);
- effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
-
- if (effect->dispatcher(effect, effEditOpen, 0, value, getContainerId(), 0.0f) != 1)
- {
- //effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
- //return false;
- qWarning("VST UI failed to open, trying to init anyway...");
- }
-
- // -----------------------------------------------------------------
- // initialize gui stuff
-
- ERect* vstRect = nullptr;
- effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0.0f);
-
- if (vstRect)
- {
- int width = vstRect->right - vstRect->left;
- int height = vstRect->bottom - vstRect->top;
-
- if (width > 0 && height > 0)
- toolkitResize(width, height);
- }
-
- idleTimer = startTimer(50);
-
- return true;
- }
-
- void close()
- {
- CarlaBridgeClient::close();
-
- if (effect)
- {
- effect->dispatcher(effect, effEditClose, 0, 0, nullptr, 0.0f);
- effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
- }
- }
-
- // ---------------------------------------------------------------------
- // ui management
-
- void* getWidget() const
- {
- return nullptr; // VST always uses reparent
- }
-
- bool isResizable() const
- {
- return false;
- }
-
- bool needsReparent() const
- {
- return true;
- }
-
- // ---------------------------------------------------------------------
- // processing
-
- void setParameter(const int32_t rindex, const double value)
- {
- if (effect)
- effect->setParameter(effect, rindex, value);
- }
-
- void setProgram(const uint32_t index)
- {
- if (effect)
- effect->dispatcher(effect, effSetProgram, 0, index, nullptr, 0.0f);
- }
-
- void setMidiProgram(const uint32_t, const uint32_t)
- {
- }
-
- void noteOn(const uint8_t, const uint8_t, const uint8_t)
- {
- }
-
- void noteOff(const uint8_t, const uint8_t)
- {
- }
-
- // ---------------------------------------------------------------------
-
- void handleAudioMasterAutomate(const uint32_t index, const float value)
- {
- effect->setParameter(effect, index, value);
-
- if (isOscControlRegistered())
- sendOscControl(index, value);
- }
-
- intptr_t handleAudioMasterGetCurrentProcessLevel()
- {
- return kVstProcessLevelUser;
- }
-
- intptr_t handleAudioMasterGetBlockSize()
- {
- return bufferSize;
- }
-
- intptr_t handleAudioMasterGetSampleRate()
- {
- return sampleRate;
- }
-
- intptr_t handleAudioMasterGetTime()
- {
- memset(&vstTimeInfo, 0, sizeof(VstTimeInfo_R));
-
- vstTimeInfo.sampleRate = sampleRate;
-
- // Tempo
- vstTimeInfo.tempo = 120.0;
- vstTimeInfo.flags |= kVstTempoValid;
-
- // Time Signature
- vstTimeInfo.timeSigNumerator = 4;
- vstTimeInfo.timeSigDenominator = 4;
- vstTimeInfo.flags |= kVstTimeSigValid;
-
- return (intptr_t)&vstTimeInfo;
- }
-
- void handleAudioMasterNeedIdle()
- {
- needIdle = true;
- }
-
- intptr_t handleAudioMasterProcessEvents(const VstEvents* const vstEvents)
- {
- if (isOscControlRegistered())
- return 1;
-
- for (int32_t i=0; i < vstEvents->numEvents; i++)
- {
- if (! vstEvents->events[i])
- break;
-
- const VstMidiEvent* const vstMidiEvent = (const VstMidiEvent*)vstEvents->events[i];
-
- if (vstMidiEvent->type != kVstMidiType)
- {
- uint8_t status = vstMidiEvent->midiData[0];
-
- // Fix bad note-off
- if (MIDI_IS_STATUS_NOTE_ON(status) && vstMidiEvent->midiData[2] == 0)
- status -= 0x10;
-
- uint8_t midiBuf[4] = { 0, status, (uint8_t)vstMidiEvent->midiData[1], (uint8_t)vstMidiEvent->midiData[2] };
- sendOscMidi(midiBuf);
- }
- }
-
- return 1;
- }
-
- intptr_t handleAdioMasterSizeWindow(int32_t width, int32_t height)
- {
- toolkitResize(width, height);
-
- return 1;
- }
-
- void handleAudioMasterUpdateDisplay()
- {
- if (isOscControlRegistered())
- sendOscConfigure("reloadprograms", "");
- }
-
- // ---------------------------------------------------------------------
-
- static intptr_t hostCanDo(const char* const feature)
- {
- qDebug("CarlaVstClient::hostCanDo(\"%s\")", feature);
-
- if (strcmp(feature, "supplyIdle") == 0)
- return 1;
- if (strcmp(feature, "sendVstEvents") == 0)
- return 1;
- if (strcmp(feature, "sendVstMidiEvent") == 0)
- return 1;
- if (strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
- return -1;
- if (strcmp(feature, "sendVstTimeInfo") == 0)
- return 1;
- if (strcmp(feature, "receiveVstEvents") == 0)
- return 1;
- if (strcmp(feature, "receiveVstMidiEvent") == 0)
- return 1;
- if (strcmp(feature, "receiveVstTimeInfo") == 0)
- return -1;
- if (strcmp(feature, "reportConnectionChanges") == 0)
- return -1;
- if (strcmp(feature, "acceptIOChanges") == 0)
- return 1;
- if (strcmp(feature, "sizeWindow") == 0)
- return 1;
- if (strcmp(feature, "offline") == 0)
- return -1;
- if (strcmp(feature, "openFileSelector") == 0)
- return -1;
- if (strcmp(feature, "closeFileSelector") == 0)
- return -1;
- if (strcmp(feature, "startStopProcess") == 0)
- return 1;
- if (strcmp(feature, "supportShell") == 0)
- return -1;
- if (strcmp(feature, "shellCategory") == 0)
- return -1;
-
- // unimplemented
- qWarning("CarlaVstClient::hostCanDo(\"%s\") - unknown feature", feature);
- return 0;
- }
-
- static intptr_t VSTCALLBACK hostCallback(AEffect* const effect, const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
- {
-#if DEBUG
- qDebug("CarlaVstClient::hostCallback(%p, %s, %i, " P_INTPTR ", %p, %f", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
-#endif
-
- // Check if 'resvd1' points to this client, or register ourselfs if possible
- CarlaVstClient* self = nullptr;
-
- if (effect)
- {
-#ifdef VESTIGE_HEADER
- if (effect && effect->ptr1)
- {
- self = (CarlaVstClient*)effect->ptr1;
-#else
- if (effect && effect->resvd1)
- {
- self = FromVstPtr(effect->resvd1);
-#endif
- if (self->unique1 != self->unique2)
- self = nullptr;
- }
-
- if (self)
- {
- if (! self->effect)
- self->effect = effect;
-
- CARLA_ASSERT(self->effect == effect);
-
- if (self->effect != effect)
- {
- qWarning("CarlaVstClient::hostCallback() - host pointer mismatch: %p != %p", self->effect, effect);
- self = nullptr;
- }
- }
- else if (lastVstPlugin)
- {
-#ifdef VESTIGE_HEADER
- effect->ptr1 = lastVstPlugin;
-#else
- effect->resvd1 = ToVstPtr(lastVstPlugin);
-#endif
- self = lastVstPlugin;
- }
- }
-
- intptr_t ret = 0;
-
- switch (opcode)
- {
- case audioMasterAutomate:
- if (self)
- self->handleAudioMasterAutomate(index, opt);
- break;
-
- case audioMasterVersion:
- ret = kVstVersion;
- break;
-
- case audioMasterCurrentId:
- // TODO
- break;
-
- case audioMasterIdle:
- //if (effect)
- // effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f);
- break;
-
- case audioMasterGetTime:
- static VstTimeInfo_R timeInfo;
- memset(&timeInfo, 0, sizeof(VstTimeInfo_R));
- timeInfo.sampleRate = sampleRate;
-
- // Tempo
- timeInfo.tempo = 120.0;
- timeInfo.flags |= kVstTempoValid;
-
- // Time Signature
- timeInfo.timeSigNumerator = 4;
- timeInfo.timeSigDenominator = 4;
- timeInfo.flags |= kVstTimeSigValid;
-
- ret = (intptr_t)&timeInfo;
- break;
-
- case audioMasterProcessEvents:
- if (self && ptr)
- ret = self->handleAudioMasterProcessEvents((const VstEvents*)ptr);
- break;
-
-#if ! VST_FORCE_DEPRECATED
- case audioMasterTempoAt:
- // Deprecated in VST SDK 2.4
- ret = 120 * 10000;
- break;
-#endif
-
- case audioMasterSizeWindow:
- if (self && index > 0 && value > 0)
- ret = self->handleAdioMasterSizeWindow(index, value);
- break;
-
- case audioMasterGetSampleRate:
- ret = sampleRate;
- break;
-
- case audioMasterGetBlockSize:
- ret = bufferSize;
- break;
-
- case audioMasterGetCurrentProcessLevel:
- ret = kVstProcessLevelUser;
- break;
-
- case audioMasterGetAutomationState:
- ret = kVstAutomationReadWrite;
- break;
-
- case audioMasterGetVendorString:
- if (ptr)
- strcpy((char*)ptr, "Cadence");
- break;
-
- case audioMasterGetProductString:
- if (ptr)
- strcpy((char*)ptr, "Carla-Bridge");
- break;
-
- case audioMasterGetVendorVersion:
- ret = 0x050; // 0.5.0
- break;
-
- case audioMasterCanDo:
- if (ptr)
- ret = hostCanDo((const char*)ptr);
- break;
-
- case audioMasterGetLanguage:
- ret = kVstLangEnglish;
- break;
-
- case audioMasterUpdateDisplay:
- if (self)
- self->handleAudioMasterUpdateDisplay();
- break;
-
- default:
-#ifdef DEBUG
- qDebug("CarlaVstClient::hostCallback(%p, %s, %i, " P_INTPTR ", %p, %f", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
-#endif
- break;
- }
-
- return ret;
- }
-
-protected:
- void timerEvent(QTimerEvent* const event)
- {
- if (event->timerId() == idleTimer && effect)
- {
- if (needIdle)
- effect->dispatcher(effect, effIdle, 0, 0, nullptr, 0.0f);
-
- effect->dispatcher(effect, effEditIdle, 0, 0, nullptr, 0.0f);
- }
-
- QObject::timerEvent(event);
- }
-
-private:
- int unique1;
-
- AEffect* effect;
- VstTimeInfo_R vstTimeInfo;
-
- int idleTimer;
- bool needIdle;
- static CarlaVstClient* lastVstPlugin;
-
- int unique2;
-};
-
-CarlaVstClient* CarlaVstClient::lastVstPlugin = nullptr;
-
-// -------------------------------------------------------------------------
-
-CARLA_BRIDGE_END_NAMESPACE
-
-int main(int argc, char* argv[])
-{
- CARLA_BRIDGE_USE_NAMESPACE
-
- if (argc != 4)
- {
- qWarning("usage: %s ", argv[0]);
- return 1;
- }
-
- const char* oscUrl = argv[1];
- const char* binary = argv[2];
- const char* uiTitle = argv[3];
-
- const bool useOsc = strcmp(oscUrl, "null");
-
- // try to get sampleRate value
- const char* const sampleRateStr = getenv("CARLA_SAMPLE_RATE");
-
- if (sampleRateStr)
- sampleRate = atof(sampleRateStr);
-
- // Init VST client
- CarlaVstClient client(uiTitle);
-
- // Init OSC
- if (useOsc && ! client.oscInit(oscUrl))
- {
- return -1;
- }
-
- // Load UI
- int ret;
-
- if (client.init(binary, nullptr))
- {
- client.toolkitExec(!useOsc);
- ret = 0;
- }
- else
- {
- qCritical("Failed to load VST UI");
- ret = 1;
- }
-
- // Close OSC
- if (useOsc)
- {
- client.oscClose();
- }
-
- // Close VST client
- client.close();
-
- return ret;
-}
-
-#endif // BRIDGE_VST
-
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro b/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro
deleted file mode 100644
index 1ac275b..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk2.pro
+++ /dev/null
@@ -1,43 +0,0 @@
-# QtCreator project file
-
-QT = core
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo gtk+-2.0
-
-TARGET = carla-bridge-lv2-gtk2
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-gtk.cpp \
- ../carla_bridge_ui-lv2.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/lv2_rdf.hpp \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-LIBS = \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_GTK2 BRIDGE_LV2_GTK2
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk3.pro b/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk3.pro
deleted file mode 100644
index 990398b..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-lv2-gtk3.pro
+++ /dev/null
@@ -1,43 +0,0 @@
-# QtCreator project file
-
-QT = core
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo gtk+-3.0
-
-TARGET = carla-bridge-lv2-gtk3
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-gtk.cpp \
- ../carla_bridge_ui-lv2.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/lv2_rdf.hpp \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-LIBS = \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_GTK3 BRIDGE_LV2_GTK3
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt4.pro b/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt4.pro
deleted file mode 100644
index c22d0bf..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt4.pro
+++ /dev/null
@@ -1,43 +0,0 @@
-# QtCreator project file
-
-QT = core gui
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo
-
-TARGET = carla-bridge-lv2-qt4
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-qt.cpp \
- ../carla_bridge_ui-lv2.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/lv2_rdf.hpp \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-LIBS = \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_QT4 BRIDGE_LV2_QT4
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt5.pro b/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt5.pro
deleted file mode 100644
index 9b335a5..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-lv2-qt5.pro
+++ /dev/null
@@ -1,43 +0,0 @@
-# QtCreator project file
-
-QT = core widgets
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo
-
-TARGET = carla-bridge-lv2-qt5
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-qt.cpp \
- ../carla_bridge_ui-lv2.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/lv2_rdf.hpp \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-LIBS = \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_QT5 BRIDGE_LV2_QT5
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-lv2-x11.pro b/c++/carla-bridge/qtcreator/carla-bridge-lv2-x11.pro
deleted file mode 100644
index 30d9697..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-lv2-x11.pro
+++ /dev/null
@@ -1,47 +0,0 @@
-# QtCreator project file
-
-contains(QT_VERSION, ^5.*) {
-QT = core widgets
-} else {
-QT = core gui
-}
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo
-
-TARGET = carla-bridge-lv2-x11
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-qt.cpp \
- ../carla_bridge_ui-lv2.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/lv2_rdf.hpp \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-LIBS = \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_LV2 BRIDGE_X11 BRIDGE_LV2_X11
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-plugin.pro b/c++/carla-bridge/qtcreator/carla-bridge-plugin.pro
deleted file mode 100644
index 649ffb7..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-plugin.pro
+++ /dev/null
@@ -1,100 +0,0 @@
-# QtCreator project file
-
-contains(QT_VERSION, ^5.*) {
-QT = core widgets xml
-} else {
-QT = core gui xml
-}
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = jack liblo
-
-TARGET = carla-bridge-qtcreator
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_plugin.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
-
-# carla
-SOURCES += \
- ../../carla/Shared.cpp
-
-HEADERS += \
- ../../carla/Shared.hpp
-
-# carla-engine
-SOURCES += \
- ../../carla-engine/carla_engine.cpp \
- ../../carla-engine/carla_engine_osc.cpp \
- ../../carla-engine/carla_engine_thread.cpp \
- ../../carla-engine/jack.cpp
-
-HEADERS += \
- ../../carla-engine/carla_engine.hpp \
- ../../carla-engine/carla_engine_osc.hpp \
- ../../carla-engine/carla_engine_thread.hpp \
-
-# carla-plugin
-SOURCES += \
- ../../carla-plugin/carla_plugin.cpp \
- ../../carla-plugin/carla_plugin_thread.cpp \
- ../../carla-plugin/ladspa.cpp \
- ../../carla-plugin/dssi.cpp \
- ../../carla-plugin/lv2.cpp \
- ../../carla-plugin/vst.cpp
-
-HEADERS += \
- ../../carla-plugin/carla_plugin.hpp \
- ../../carla-plugin/carla_plugin_thread.hpp
-
-# carla-backend
-HEADERS += \
- ../../carla-backend/carla_backend.hpp \
- ../../carla-backend/carla_backend_utils.hpp
-
-# carla-includes
-HEADERS += \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-includes/ladspa_rdf.hpp \
- ../../carla-includes/lv2_rdf.hpp
-
-# carla-utils
-HEADERS += \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_ladspa_utils.hpp \
- ../../carla-utils/carla_lv2_utils.hpp \
- ../../carla-utils/carla_vst_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-backend \
- ../../carla-engine \
- ../../carla-includes \
- ../../carla-jackbridge \
- ../../carla-plugin \
- ../../carla-utils
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-#DEFINES += VESTIGE_HEADER
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_PLUGIN BRIDGE_PLUGIN
-
-DEFINES += CARLA_ENGINE_JACK
-DEFINES += WANT_LADSPA WANT_DSSI WANT_LV2 WANT_VST
-
-LIBS = -ldl \
- ../../carla-lilv/carla_lilv.a \
- ../../carla-rtmempool/carla_rtmempool.a
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-bridge/qtcreator/carla-bridge-vst-x11.pro b/c++/carla-bridge/qtcreator/carla-bridge-vst-x11.pro
deleted file mode 100644
index 8d11d7d..0000000
--- a/c++/carla-bridge/qtcreator/carla-bridge-vst-x11.pro
+++ /dev/null
@@ -1,42 +0,0 @@
-# QtCreator project file
-
-contains(QT_VERSION, ^5.*) {
-QT = core widgets
-} else {
-QT = core gui
-}
-
-CONFIG = debug link_pkgconfig qt warn_on
-PKGCONFIG = liblo
-
-TARGET = carla-bridge-vst-x11
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- ../carla_bridge_client.cpp \
- ../carla_bridge_osc.cpp \
- ../carla_bridge_toolkit.cpp \
- ../carla_bridge_toolkit-qt.cpp \
- ../carla_bridge_ui-vst.cpp
-
-HEADERS = \
- ../carla_bridge.hpp \
- ../carla_bridge_client.hpp \
- ../carla_bridge_osc.hpp \
- ../carla_bridge_toolkit.hpp \
- ../../carla-includes/carla_defines.hpp \
- ../../carla-includes/carla_midi.h \
- ../../carla-utils/carla_lib_utils.hpp \
- ../../carla-utils/carla_osc_utils.hpp \
- ../../carla-utils/carla_vst_utils.hpp
-
-INCLUDEPATH = .. \
- ../../carla-includes \
- ../../carla-utils
-
-DEFINES = QTCREATOR_TEST
-DEFINES += DEBUG
-DEFINES += BUILD_BRIDGE BUILD_BRIDGE_UI BRIDGE_VST BRIDGE_X11 BRIDGE_VST_X11
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-discovery/Makefile b/c++/carla-discovery/Makefile
deleted file mode 100644
index 3e8db4a..0000000
--- a/c++/carla-discovery/Makefile
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/make -f
-# Makefile for carla-discovery #
-# ----------------------------------------- #
-# Created by falkTX
-#
-
-include ../Makefile.mk
-
-# --------------------------------------------------------------
-
-BUILD_CXX_FLAGS += -I../carla-backend -I../carla-includes -I../carla-utils
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags QtCore)
-LINK_FLAGS += $(shell pkg-config --libs QtCore)
-
-ifeq ($(CARLA_PLUGIN_SUPPORT),true)
-BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST
-endif
-
-ifneq ($(NATIVE),)
-ifeq ($(HAVE_FLUIDSYNTH),true)
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags fluidsynth) -DWANT_FLUIDSYNTH
-LINK_FLAGS += $(shell pkg-config --libs fluidsynth)
-endif
-
-ifeq ($(HAVE_LINUXSAMPLER),true)
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags linuxsampler) -DWANT_LINUXSAMPLER
-LINK_FLAGS += $(shell pkg-config --libs linuxsampler)
-endif
-endif
-
-# --------------------------------------------------------------
-
-POSIX_BUILD_FLAGS = $(BUILD_CXX_FLAGS)
-POSIX_32BIT_FLAGS = $(32BIT_FLAGS) -L/usr/lib32 -L/usr/lib/i386-linux-gnu
-POSIX_64BIT_FLAGS = $(64BIT_FLAGS) -L/usr/lib64 -L/usr/lib/x86_64-linux-gnu
-POSIX_LINK_FLAGS = $(LINK_FLAGS) -ldl -lpthread
-
-WIN_BUILD_FLAGS = $(BUILD_CXX_FLAGS)
-WIN_32BIT_FLAGS = $(32BIT_FLAGS)
-WIN_64BIT_FLAGS = $(64BIT_FLAGS)
-WIN_LINK_FLAGS = $(LINK_FLAGS) -static -mwindows
-
-# --------------------------------------------------------------
-
-all: carla-discovery-native
-
-posix32: carla-discovery-posix32
-posix64: carla-discovery-posix64
-win32: carla-discovery-win32.exe
-win64: carla-discovery-win64.exe
-
-# --------------------------------------------------------------
-
-OBJS = carla-discovery.cpp
-
-carla-discovery-native: $(OBJS) ../carla-lilv/carla_lilv.a
- $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-carla-discovery-posix32: $(OBJS) ../carla-lilv/carla_lilv_posix32.a
- $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_32BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-carla-discovery-posix64: $(OBJS) ../carla-lilv/carla_lilv_posix64.a
- $(CXX) $^ $(POSIX_BUILD_FLAGS) $(POSIX_64BIT_FLAGS) $(POSIX_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-carla-discovery-win32.exe: $(OBJS) ../carla-lilv/carla_lilv_win32.a
- $(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_32BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-carla-discovery-win64.exe: $(OBJS) ../carla-lilv/carla_lilv_win64.a
- $(CXX) $^ $(WIN_BUILD_FLAGS) $(WIN_64BIT_FLAGS) $(WIN_LINK_FLAGS) -o $@ && $(STRIP) $@
-
-# --------------------------------------------------------------
-
-../carla-lilv/carla_lilv.a:
- $(MAKE) -C ../carla-lilv
-
-../carla-lilv/carla_lilv_posix32.a:
- $(MAKE) -C ../carla-lilv posix32
-
-../carla-lilv/carla_lilv_posix64.a:
- $(MAKE) -C ../carla-lilv posix64
-
-../carla-lilv/carla_lilv_win32.a:
- $(MAKE) -C ../carla-lilv win32
-
-../carla-lilv/carla_lilv_win64.a:
- $(MAKE) -C ../carla-lilv win64
-
-# --------------------------------------------------------------
-
-clean:
- rm -f carla-discovery-*
diff --git a/c++/carla-discovery/carla-discovery.cpp b/c++/carla-discovery/carla-discovery.cpp
deleted file mode 100644
index beb3a6d..0000000
--- a/c++/carla-discovery/carla-discovery.cpp
+++ /dev/null
@@ -1,1337 +0,0 @@
-/*
- * Carla Plugin discovery code
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include
-#include
-#include
-#include
-
-#include "carla_backend.hpp"
-#include "carla_lib_utils.hpp"
-
-#ifdef WANT_LADSPA
-# include "carla_ladspa_utils.hpp"
-#endif
-#ifdef WANT_DSSI
-# include "carla_ladspa_utils.hpp"
-# include "dssi/dssi.h"
-#endif
-#ifdef WANT_LV2
-# include "carla_lv2_utils.hpp"
-#endif
-#ifdef WANT_VST
-# include "carla_vst_utils.hpp"
-#endif
-#ifdef WANT_FLUIDSYNTH
-# include
-#endif
-#ifdef WANT_LINUXSAMPLER
-# include "linuxsampler/EngineFactory.h"
-#endif
-
-#define DISCOVERY_OUT(x, y) std::cout << "\ncarla-discovery::" << x << "::" << y << std::endl;
-
-// Fake values to test plugins with
-const uint32_t bufferSize = 512;
-const double sampleRate = 44100.0;
-
-// Since discovery can find multi-architecture binaries, don't print ELF/EXE related errors
-void print_lib_error(const char* const filename)
-{
- const char* const error = lib_error(filename);
- if (error && strstr(error, "wrong ELF class") == nullptr && strstr(error, "Bad EXE format") == nullptr)
- DISCOVERY_OUT("error", error);
-}
-
-using namespace CarlaBackend;
-
-// ------------------------------ VST Stuff ------------------------------
-
-#ifdef WANT_VST
-bool vstWantsMidi = false;
-intptr_t vstCurrentUniqueId = 0;
-
-intptr_t vstHostCanDo(const char* const feature)
-{
- qDebug("vstHostCanDo(\"%s\")", feature);
-
- if (strcmp(feature, "supplyIdle") == 0)
- return 1;
- if (strcmp(feature, "sendVstEvents") == 0)
- return 1;
- if (strcmp(feature, "sendVstMidiEvent") == 0)
- return 1;
- if (strcmp(feature, "sendVstMidiEventFlagIsRealtime") == 0)
- return -1;
- if (strcmp(feature, "sendVstTimeInfo") == 0)
- return 1;
- if (strcmp(feature, "receiveVstEvents") == 0)
- return 1;
- if (strcmp(feature, "receiveVstMidiEvent") == 0)
- return 1;
- if (strcmp(feature, "receiveVstTimeInfo") == 0)
- return -1;
- if (strcmp(feature, "reportConnectionChanges") == 0)
- return -1;
- if (strcmp(feature, "acceptIOChanges") == 0)
- return 1;
- if (strcmp(feature, "sizeWindow") == 0)
- return 1;
- if (strcmp(feature, "offline") == 0)
- return -1;
- if (strcmp(feature, "openFileSelector") == 0)
- return -1;
- if (strcmp(feature, "closeFileSelector") == 0)
- return -1;
- if (strcmp(feature, "startStopProcess") == 0)
- return 1;
- if (strcmp(feature, "supportShell") == 0)
- return 1;
- if (strcmp(feature, "shellCategory") == 0)
- return 1;
-
- // unimplemented
- qWarning("vstHostCanDo(\"%s\") - unknown feature", feature);
- return 0;
-}
-
-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)
-{
-#if DEBUG
- qDebug("vstHostCallback(%p, %s, %i, " P_INTPTR ", %p, %f)", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
-#endif
-
- intptr_t ret = 0;
-
- switch (opcode)
- {
- case audioMasterAutomate:
- if (effect)
- {
- effect->setParameter(effect, index, opt);
- ret = 1;
- }
- break;
-
- case audioMasterVersion:
- ret = kVstVersion;
- break;
-
- case audioMasterCurrentId:
- ret = vstCurrentUniqueId;
- break;
-
-#if ! VST_FORCE_DEPRECATED
- case audioMasterWantMidi:
- vstWantsMidi = true;
- ret = 1;
- break;
-#endif
-
- case audioMasterGetTime:
- static VstTimeInfo_R timeInfo;
- memset(&timeInfo, 0, sizeof(VstTimeInfo_R));
- timeInfo.sampleRate = sampleRate;
-
- // Tempo
- timeInfo.tempo = 120.0;
- timeInfo.flags |= kVstTempoValid;
-
- // Time Signature
- timeInfo.timeSigNumerator = 4;
- timeInfo.timeSigDenominator = 4;
- timeInfo.flags |= kVstTimeSigValid;
-
- ret = (intptr_t)&timeInfo;
- break;
-
-#if ! VST_FORCE_DEPRECATED
- case audioMasterTempoAt:
- ret = 120 * 10000;
- break;
-
- case audioMasterGetNumAutomatableParameters:
- ret = carla_minPositiveI(effect->numParams, MAX_PARAMETERS);
- break;
-
- case audioMasterGetParameterQuantization:
- ret = 1; // full single float precision
- break;
-#endif
-
- case audioMasterGetSampleRate:
- ret = sampleRate;
- break;
-
- case audioMasterGetBlockSize:
- ret = bufferSize;
- break;
-
-#if ! VST_FORCE_DEPRECATED
- case audioMasterWillReplaceOrAccumulate:
- ret = 1; // replace
- break;
-#endif
-
- case audioMasterGetCurrentProcessLevel:
- ret = kVstProcessLevelUser;
- break;
-
- case audioMasterGetAutomationState:
- ret = kVstAutomationOff;
- break;
-
- case audioMasterGetVendorString:
- if (ptr)
- {
- strcpy((char*)ptr, "Cadence");
- ret = 1;
- }
- break;
-
- case audioMasterGetProductString:
- if (ptr)
- {
- strcpy((char*)ptr, "Carla-Discovery");
- ret = 1;
- }
- break;
-
- case audioMasterGetVendorVersion:
- ret = 0x050; // 0.5.0
- break;
-
- case audioMasterCanDo:
- if (ptr)
- ret = vstHostCanDo((const char*)ptr);
- break;
-
- case audioMasterGetLanguage:
- ret = kVstLangEnglish;
- break;
-
- default:
- qDebug("vstHostCallback(%p, %s, %i, " P_INTPTR ", %p, %f)", effect, vstMasterOpcode2str(opcode), index, value, ptr, opt);
- break;
- }
-
- return ret;
-}
-#endif
-
-// ------------------------------ Plugin Checks -----------------------------
-
-void do_ladspa_check(void* const libHandle, const bool init)
-{
-#ifdef WANT_LADSPA
- const LADSPA_Descriptor_Function descFn = (LADSPA_Descriptor_Function)lib_symbol(libHandle, "ladspa_descriptor");
-
- if (! descFn)
- {
- DISCOVERY_OUT("error", "Not a LADSPA plugin");
- return;
- }
-
- unsigned long i = 0;
- const LADSPA_Descriptor* descriptor;
-
- while ((descriptor = descFn(i++)))
- {
- CARLA_ASSERT(descriptor->run);
-
- int hints = 0;
- int audioIns = 0;
- int audioOuts = 0;
- int audioTotal = 0;
- int parametersIns = 0;
- int parametersOuts = 0;
- int parametersTotal = 0;
-
- for (unsigned long j=0; j < descriptor->PortCount; j++)
- {
- const LADSPA_PortDescriptor portDescriptor = descriptor->PortDescriptors[j];
-
- if (LADSPA_IS_PORT_AUDIO(portDescriptor))
- {
- if (LADSPA_IS_PORT_INPUT(portDescriptor))
- audioIns += 1;
- else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
- audioOuts += 1;
- audioTotal += 1;
- }
- else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
- {
- if (LADSPA_IS_PORT_INPUT(portDescriptor))
- parametersIns += 1;
- else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(descriptor->PortNames[j], "latency") && strcmp(descriptor->PortNames[j], "_latency") && strcmp(descriptor->PortNames[j], "_sample-rate"))
- parametersOuts += 1;
- parametersTotal += 1;
- }
- }
-
- if (init)
- {
- // -----------------------------------------------------------------------
- // start crash-free plugin test
-
- const LADSPA_Handle handle = descriptor->instantiate(descriptor, sampleRate);
-
- if (! handle)
- {
- DISCOVERY_OUT("error", "Failed to init LADSPA plugin");
- continue;
- }
-
- LADSPA_Data bufferAudio[bufferSize][audioTotal];
- LADSPA_Data bufferParams[parametersTotal];
- LADSPA_Data min, max, def;
-
- for (unsigned long j=0, iA=0, iP=0; j < descriptor->PortCount; j++)
- {
- const LADSPA_PortDescriptor portType = descriptor->PortDescriptors[j];
- const LADSPA_PortRangeHint portHints = descriptor->PortRangeHints[j];
-
- if (LADSPA_IS_PORT_AUDIO(portType))
- {
- carla_zeroF(bufferAudio[iA], bufferSize);
- descriptor->connect_port(handle, j, bufferAudio[iA++]);
- }
- else if (LADSPA_IS_PORT_CONTROL(portType))
- {
- // min value
- if (LADSPA_IS_HINT_BOUNDED_BELOW(portHints.HintDescriptor))
- min = portHints.LowerBound;
- else
- min = 0.0f;
-
- // max value
- if (LADSPA_IS_HINT_BOUNDED_ABOVE(portHints.HintDescriptor))
- max = portHints.UpperBound;
- else
- max = 1.0f;
-
- if (min > max)
- max = min;
- else if (max < min)
- min = max;
-
- if (max - min == 0.0f)
- {
- DISCOVERY_OUT("error", "Broken parameter '" << descriptor->PortNames[j] << "': max - min == 0");
- max = min + 0.1f;
- }
-
- // default value
- def = get_default_ladspa_port_value(portHints.HintDescriptor, min, max);
-
- if (LADSPA_IS_HINT_SAMPLE_RATE(portHints.HintDescriptor))
- {
- min *= sampleRate;
- max *= sampleRate;
- def *= sampleRate;
- }
-
- if (LADSPA_IS_PORT_OUTPUT(portType) && (strcmp(descriptor->PortNames[j], "latency") == 0 || strcmp(descriptor->PortNames[j], "_latency") == 0))
- {
- // latency parameter
- min = 0.0f;
- max = sampleRate;
- def = 0.0f;
- }
-
- if (def < min)
- def = min;
- else if (def > max)
- def = max;
-
- bufferParams[iP] = def;
-
- descriptor->connect_port(handle, j, &bufferParams[iP++]);
- }
- }
-
- if (descriptor->activate)
- descriptor->activate(handle);
-
- if (descriptor->run)
- descriptor->run(handle, bufferSize);
-
- if (descriptor->deactivate)
- descriptor->deactivate(handle);
-
- if (descriptor->cleanup)
- descriptor->cleanup(handle);
-
- // end crash-free plugin test
- // -----------------------------------------------------------------------
- }
-
- DISCOVERY_OUT("init", "-----------");
- DISCOVERY_OUT("name", descriptor->Name);
- DISCOVERY_OUT("label", descriptor->Label);
- DISCOVERY_OUT("maker", descriptor->Maker);
- DISCOVERY_OUT("copyright", descriptor->Copyright);
- DISCOVERY_OUT("unique_id", descriptor->UniqueID);
- DISCOVERY_OUT("hints", hints);
- DISCOVERY_OUT("audio.ins", audioIns);
- DISCOVERY_OUT("audio.outs", audioOuts);
- DISCOVERY_OUT("audio.total", audioTotal);
- DISCOVERY_OUT("parameters.ins", parametersIns);
- DISCOVERY_OUT("parameters.outs", parametersOuts);
- DISCOVERY_OUT("parameters.total", parametersTotal);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
- }
-#else
- DISCOVERY_OUT("error", "LADSPA support not available");
- Q_UNUSED(libHandle);
- Q_UNUSED(init);
-#endif
-}
-
-void do_dssi_check(void* const libHandle, const bool init)
-{
-#ifdef WANT_DSSI
- const DSSI_Descriptor_Function descFn = (DSSI_Descriptor_Function)lib_symbol(libHandle, "dssi_descriptor");
-
- if (! descFn)
- {
- DISCOVERY_OUT("error", "Not a DSSI plugin");
- return;
- }
-
- unsigned long i = 0;
- const DSSI_Descriptor* descriptor;
-
- while ((descriptor = descFn(i++)))
- {
- const LADSPA_Descriptor* const ldescriptor = descriptor->LADSPA_Plugin;
- CARLA_ASSERT(ldescriptor);
- CARLA_ASSERT(ldescriptor->run || descriptor->run_synth || descriptor->run_multiple_synths);
-
- int hints = 0;
- int audioIns = 0;
- int audioOuts = 0;
- int audioTotal = 0;
- int midiIns = 0;
- int midiTotal = 0;
- int parametersIns = 0;
- int parametersOuts = 0;
- int parametersTotal = 0;
- int programsTotal = 0;
-
- for (unsigned long j=0; j < ldescriptor->PortCount; j++)
- {
- const LADSPA_PortDescriptor portDescriptor = ldescriptor->PortDescriptors[j];
-
- if (LADSPA_IS_PORT_AUDIO(portDescriptor))
- {
- if (LADSPA_IS_PORT_INPUT(portDescriptor))
- audioIns += 1;
- else if (LADSPA_IS_PORT_OUTPUT(portDescriptor))
- audioOuts += 1;
- audioTotal += 1;
- }
- else if (LADSPA_IS_PORT_CONTROL(portDescriptor))
- {
- if (LADSPA_IS_PORT_INPUT(portDescriptor))
- parametersIns += 1;
- else if (LADSPA_IS_PORT_OUTPUT(portDescriptor) && strcmp(ldescriptor->PortNames[j], "latency") && strcmp(ldescriptor->PortNames[j], "_latency") && strcmp(ldescriptor->PortNames[j], "_sample-rate"))
- parametersOuts += 1;
- parametersTotal += 1;
- }
- }
-
- if (descriptor->run_synth || descriptor->run_multiple_synths)
- midiIns = midiTotal = 1;
-
- if (midiIns > 0 && audioOuts > 0)
- hints |= PLUGIN_IS_SYNTH;
-
- if (init)
- {
- // -----------------------------------------------------------------------
- // start crash-free plugin test
-
- const LADSPA_Handle handle = ldescriptor->instantiate(ldescriptor, sampleRate);
-
- if (! handle)
- {
- DISCOVERY_OUT("error", "Failed to init DSSI plugin");
- continue;
- }
-
- // we can only get program info per-handle
- if (descriptor->get_program && descriptor->select_program)
- {
- while ((descriptor->get_program(handle, programsTotal++)))
- continue;
- }
-
- LADSPA_Data bufferAudio[bufferSize][audioTotal];
- LADSPA_Data bufferParams[parametersTotal];
- LADSPA_Data min, max, def;
-
- for (unsigned long j=0, iA=0, iP=0; j < ldescriptor->PortCount; j++)
- {
- const LADSPA_PortDescriptor portType = ldescriptor->PortDescriptors[j];
- const LADSPA_PortRangeHint portHints = ldescriptor->PortRangeHints[j];
-
- if (LADSPA_IS_PORT_AUDIO(portType))
- {
- carla_zeroF(bufferAudio[iA], bufferSize);
- ldescriptor->connect_port(handle, j, bufferAudio[iA++]);
- }
- else if (LADSPA_IS_PORT_CONTROL(portType))
- {
- // min value
- if (LADSPA_IS_HINT_BOUNDED_BELOW(portHints.HintDescriptor))
- min = portHints.LowerBound;
- else
- min = 0.0f;
-
- // max value
- if (LADSPA_IS_HINT_BOUNDED_ABOVE(portHints.HintDescriptor))
- max = portHints.UpperBound;
- else
- max = 1.0f;
-
- if (min > max)
- max = min;
- else if (max < min)
- min = max;
-
- if (max - min == 0.0f)
- {
- DISCOVERY_OUT("error", "Broken parameter '" << ldescriptor->PortNames[j] << "': max - min == 0");
- max = min + 0.1f;
- }
-
- // default value
- def = get_default_ladspa_port_value(portHints.HintDescriptor, min, max);
-
- if (LADSPA_IS_HINT_SAMPLE_RATE(portHints.HintDescriptor))
- {
- min *= sampleRate;
- max *= sampleRate;
- def *= sampleRate;
- }
-
- if (LADSPA_IS_PORT_OUTPUT(portType) && (strcmp(ldescriptor->PortNames[j], "latency") == 0 || strcmp(ldescriptor->PortNames[j], "_latency") == 0))
- {
- // latency parameter
- min = 0.0f;
- max = sampleRate;
- def = 0.0f;
- }
-
- if (def < min)
- def = min;
- else if (def > max)
- def = max;
-
- bufferParams[iP] = def;
-
- ldescriptor->connect_port(handle, j, &bufferParams[iP++]);
- }
- }
-
- // select first midi-program if available
- if (programsTotal > 0)
- {
- const DSSI_Program_Descriptor* pDesc = descriptor->get_program(handle, 0);
- CARLA_ASSERT(pDesc);
-
- if (pDesc)
- descriptor->select_program(handle, pDesc->Bank, pDesc->Program);
- }
-
- if (ldescriptor->activate)
- ldescriptor->activate(handle);
-
- if (descriptor->run_synth || descriptor->run_multiple_synths)
- {
- snd_seq_event_t midiEvents[2];
- memset(midiEvents, 0, sizeof(snd_seq_event_t)*2);
-
- const unsigned long midiEventCount = 2;
-
- midiEvents[0].type = SND_SEQ_EVENT_NOTEON;
- midiEvents[0].data.note.note = 64;
- midiEvents[0].data.note.velocity = 100;
-
- midiEvents[1].type = SND_SEQ_EVENT_NOTEOFF;
- midiEvents[1].data.note.note = 64;
- midiEvents[1].data.note.velocity = 0;
- midiEvents[1].time.tick = bufferSize/2;
-
- if (descriptor->run_multiple_synths && ! descriptor->run_synth)
- {
- LADSPA_Handle handlePtr[1] = { handle };
- snd_seq_event_t* midiEventsPtr[1] = { midiEvents };
- unsigned long midiEventCountPtr[1] = { midiEventCount };
- descriptor->run_multiple_synths(1, handlePtr, bufferSize, midiEventsPtr, midiEventCountPtr);
- }
- else
- descriptor->run_synth(handle, bufferSize, midiEvents, midiEventCount);
- }
- else if (ldescriptor->run)
- ldescriptor->run(handle, bufferSize);
-
- if (ldescriptor->deactivate)
- ldescriptor->deactivate(handle);
-
- if (ldescriptor->cleanup)
- ldescriptor->cleanup(handle);
-
- // end crash-free plugin test
- // -----------------------------------------------------------------------
- }
-
- DISCOVERY_OUT("init", "-----------");
- DISCOVERY_OUT("name", ldescriptor->Name);
- DISCOVERY_OUT("label", ldescriptor->Label);
- DISCOVERY_OUT("maker", ldescriptor->Maker);
- DISCOVERY_OUT("copyright", ldescriptor->Copyright);
- DISCOVERY_OUT("unique_id", ldescriptor->UniqueID);
- DISCOVERY_OUT("hints", hints);
- DISCOVERY_OUT("audio.ins", audioIns);
- DISCOVERY_OUT("audio.outs", audioOuts);
- DISCOVERY_OUT("audio.total", audioTotal);
- DISCOVERY_OUT("midi.ins", midiIns);
- DISCOVERY_OUT("midi.total", midiTotal);
- DISCOVERY_OUT("parameters.ins", parametersIns);
- DISCOVERY_OUT("parameters.outs", parametersOuts);
- DISCOVERY_OUT("parameters.total", parametersTotal);
- DISCOVERY_OUT("programs.total", programsTotal);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
- }
-#else
- DISCOVERY_OUT("error", "DSSI support not available");
- Q_UNUSED(libHandle);
- Q_UNUSED(init);
-#endif
-}
-
-void do_lv2_check(const char* const bundle, const bool init)
-{
-#ifdef WANT_LV2
- // Convert bundle filename to URI
- QString qBundle(QUrl::fromLocalFile(bundle).toString());
- if (! qBundle.endsWith(QDir::separator()))
- qBundle += QDir::separator();
-
- // Load bundle
- Lilv::Node lilvBundle(lv2World.new_uri(qBundle.toUtf8().constData()));
- lv2World.load_bundle(lilvBundle);
-
- // Load plugins in this bundle
- const Lilv::Plugins lilvPlugins = lv2World.get_all_plugins();
-
- // Get all plugin URIs in this bundle
- QStringList URIs;
-
- LILV_FOREACH(plugins, i, lilvPlugins)
- {
- Lilv::Plugin lilvPlugin(lilv_plugins_get(lilvPlugins, i));
- URIs.append(QString(lilvPlugin.get_uri().as_string()));
- }
-
- // Get & check every plugin-instance
- for (int i=0; i < URIs.count(); i++)
- {
- const LV2_RDF_Descriptor* const rdf_descriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData());
- CARLA_ASSERT(rdf_descriptor && rdf_descriptor->URI);
-
- if (! (rdf_descriptor && rdf_descriptor->URI))
- {
- DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URIs.at(i).toUtf8().constData() << "'");
- continue;
- }
-
- if (init)
- {
- // test if DLL is loadable
- void* const libHandle = lib_open(rdf_descriptor->Binary);
-
- if (! libHandle)
- {
- print_lib_error(rdf_descriptor->Binary);
- delete rdf_descriptor;
- continue;
- }
-
- lib_close(libHandle);
-
- // test if we support all required ports and features
- bool supported = true;
-
- for (uint32_t j=0; j < rdf_descriptor->PortCount; j++)
- {
- const LV2_RDF_Port* const port = &rdf_descriptor->Ports[j];
- bool validPort = (LV2_IS_PORT_CONTROL(port->Type) || LV2_IS_PORT_AUDIO(port->Type) || LV2_IS_PORT_ATOM_SEQUENCE(port->Type) /*|| LV2_IS_PORT_CV(port->Type)*/ || LV2_IS_PORT_EVENT(port->Type) || LV2_IS_PORT_MIDI_LL(port->Type));
-
- if (! (validPort || LV2_IS_PORT_OPTIONAL(port->Properties)))
- {
- DISCOVERY_OUT("error", "plugin requires a non-supported port type, port-name: " << port->Name);
- supported = false;
- break;
- }
- }
-
- for (uint32_t j=0; j < rdf_descriptor->FeatureCount && supported; j++)
- {
- const LV2_RDF_Feature* const feature = &rdf_descriptor->Features[j];
-
- if (LV2_IS_FEATURE_REQUIRED(feature->Type) && ! is_lv2_feature_supported(feature->URI))
- {
- DISCOVERY_OUT("error", "plugin requires a non-supported feature " << feature->URI);
- supported = false;
- break;
- }
- }
-
- if (! supported)
- {
- delete rdf_descriptor;
- continue;
- }
- }
-
- int hints = 0;
- int audioIns = 0;
- int audioOuts = 0;
- int audioTotal = 0;
- int midiIns = 0;
- int midiOuts = 0;
- int midiTotal = 0;
- int parametersIns = 0;
- int parametersOuts = 0;
- int parametersTotal = 0;
-
- for (uint32_t j=0; j < rdf_descriptor->PortCount; j++)
- {
- const LV2_RDF_Port* const port = &rdf_descriptor->Ports[j];
-
- if (LV2_IS_PORT_AUDIO(port->Type))
- {
- if (LV2_IS_PORT_INPUT(port->Type))
- audioIns += 1;
- else if (LV2_IS_PORT_OUTPUT(port->Type))
- audioOuts += 1;
- audioTotal += 1;
- }
- else if (LV2_IS_PORT_CONTROL(port->Type))
- {
- if (LV2_IS_PORT_DESIGNATION_LATENCY(port->Designation) || LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(port->Designation) ||
- LV2_IS_PORT_DESIGNATION_FREEWHEELING(port->Designation) || LV2_IS_PORT_DESIGNATION_TIME(port->Designation))
- {
- pass();
- }
- else
- {
- if (LV2_IS_PORT_INPUT(port->Type))
- parametersIns += 1;
- else if (LV2_IS_PORT_OUTPUT(port->Type))
- parametersOuts += 1;
- parametersTotal += 1;
- }
- }
- else if (port->Type & LV2_PORT_SUPPORTS_MIDI_EVENT)
- {
- if (LV2_IS_PORT_INPUT(port->Type))
- midiIns += 1;
- else if (LV2_IS_PORT_OUTPUT(port->Type))
- midiOuts += 1;
- midiTotal += 1;
- }
- }
-
- if (rdf_descriptor->Type & LV2_CLASS_INSTRUMENT)
- hints |= PLUGIN_IS_SYNTH;
-
- if (rdf_descriptor->UICount > 0)
- hints |= PLUGIN_HAS_GUI;
-
- DISCOVERY_OUT("init", "-----------");
- DISCOVERY_OUT("label", rdf_descriptor->URI);
- if (rdf_descriptor->Name)
- DISCOVERY_OUT("name", rdf_descriptor->Name);
- if (rdf_descriptor->Author)
- DISCOVERY_OUT("maker", rdf_descriptor->Author);
- if (rdf_descriptor->License)
- DISCOVERY_OUT("copyright", rdf_descriptor->License);
- DISCOVERY_OUT("unique_id", rdf_descriptor->UniqueID);
- DISCOVERY_OUT("hints", hints);
- DISCOVERY_OUT("audio.ins", audioIns);
- DISCOVERY_OUT("audio.outs", audioOuts);
- DISCOVERY_OUT("audio.total", audioTotal);
- DISCOVERY_OUT("midi.ins", midiIns);
- DISCOVERY_OUT("midi.outs", midiOuts);
- DISCOVERY_OUT("midi.total", midiTotal);
- DISCOVERY_OUT("parameters.ins", parametersIns);
- DISCOVERY_OUT("parameters.outs", parametersOuts);
- DISCOVERY_OUT("parameters.total", parametersTotal);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
-
- delete rdf_descriptor;
- }
-#else
- DISCOVERY_OUT("error", "LV2 support not available");
- Q_UNUSED(bundle);
- Q_UNUSED(init);
-#endif
-}
-
-void do_vst_check(void* const libHandle, const bool init)
-{
-#ifdef WANT_VST
- VST_Function vstFn = (VST_Function)lib_symbol(libHandle, "VSTPluginMain");
-
- if (! vstFn)
- vstFn = (VST_Function)lib_symbol(libHandle, "main");
-
- if (! vstFn)
- {
- DISCOVERY_OUT("error", "Not a VST plugin");
- return;
- }
-
- AEffect* const effect = vstFn(vstHostCallback);
-
- if (! (effect && effect->magic == kEffectMagic))
- {
- DISCOVERY_OUT("error", "Failed to init VST plugin, or VST magic failed");
- return;
- }
-
- const char* cName;
- const char* cProduct;
- const char* cVendor;
- char strBuf[255] = { 0 };
-
- effect->dispatcher(effect, effOpen, 0, 0, nullptr, 0.0f);
-
- effect->dispatcher(effect, effGetEffectName, 0, 0, strBuf, 0.0f);
- cName = strdup((strBuf[0] != 0) ? strBuf : "");
-
- strBuf[0] = 0;
- effect->dispatcher(effect, effGetProductString, 0, 0, strBuf, 0.0f);
- cProduct = strdup((strBuf[0] != 0) ? strBuf : "");
-
- strBuf[0] = 0;
- effect->dispatcher(effect, effGetVendorString, 0, 0, strBuf, 0.0f);
- cVendor = strdup((strBuf[0] != 0) ? strBuf : "");
-
- vstCurrentUniqueId = effect->uniqueID;
- intptr_t vstCategory = effect->dispatcher(effect, effGetPlugCategory, 0, 0, nullptr, 0.0f);
-
- while (true)
- {
- int hints = 0;
- int audioIns = effect->numInputs;
- int audioOuts = effect->numOutputs;
- int audioTotal = audioIns + audioOuts;
- int midiIns = 0;
- int midiOuts = 0;
- int midiTotal = 0;
- int parametersIns = effect->numParams;
- int parametersTotal = parametersIns;
- int programsTotal = effect->numPrograms;
-
- if (effect->flags & effFlagsHasEditor)
- hints |= PLUGIN_HAS_GUI;
-
- if (effect->flags & effFlagsIsSynth)
- hints |= PLUGIN_IS_SYNTH;
-
- if (vstPluginCanDo(effect, "receiveVstEvents") || vstPluginCanDo(effect, "receiveVstMidiEvent") || vstWantsMidi || (effect->flags & effFlagsIsSynth) > 0)
- midiIns = 1;
-
- if (vstPluginCanDo(effect, "sendVstEvents") || vstPluginCanDo(effect, "sendVstMidiEvent"))
- midiOuts = 1;
-
- midiTotal = midiIns + midiOuts;
-
- // -----------------------------------------------------------------------
- // start crash-free plugin test
-
- if (init)
- {
- float** bufferAudioIn = new float* [audioIns];
- for (int j=0; j < audioIns; j++)
- {
- bufferAudioIn[j] = new float [bufferSize];
- memset(bufferAudioIn[j], 0, sizeof(float)*bufferSize);
- }
-
- float** bufferAudioOut = new float* [audioOuts];
- for (int j=0; j < audioOuts; j++)
- {
- bufferAudioOut[j] = new float [bufferSize];
- memset(bufferAudioOut[j], 0, sizeof(float)*bufferSize);
- }
-
- struct {
- int32_t numEvents;
- intptr_t reserved;
- VstEvent* data[2];
- } events;
- VstMidiEvent midiEvents[2];
- memset(midiEvents, 0, sizeof(VstMidiEvent)*2);
-
- midiEvents[0].type = kVstMidiType;
- midiEvents[0].byteSize = sizeof(VstMidiEvent);
- midiEvents[0].midiData[0] = 0x90;
- midiEvents[0].midiData[1] = 64;
- midiEvents[0].midiData[2] = 100;
-
- midiEvents[1].type = kVstMidiType;
- midiEvents[1].byteSize = sizeof(VstMidiEvent);
- midiEvents[1].midiData[0] = 0x80;
- midiEvents[1].midiData[1] = 64;
- midiEvents[1].deltaFrames = bufferSize/2;
-
- events.numEvents = 2;
- events.reserved = 0;
- events.data[0] = (VstEvent*)&midiEvents[0];
- events.data[1] = (VstEvent*)&midiEvents[1];
-
-#if ! VST_FORCE_DEPRECATED
- effect->dispatcher(effect, effSetBlockSizeAndSampleRate, 0, bufferSize, nullptr, sampleRate);
-#endif
- effect->dispatcher(effect, effSetBlockSize, 0, bufferSize, nullptr, 0.0f);
- effect->dispatcher(effect, effSetSampleRate, 0, 0, nullptr, sampleRate);
- effect->dispatcher(effect, effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
-
- effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
- effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
-
- if (midiIns > 0)
- effect->dispatcher(effect, effProcessEvents, 0, 0, &events, 0.0f);
-
-#if ! VST_FORCE_DEPRECATED
- if ((effect->flags & effFlagsCanReplacing) > 0 && effect->processReplacing != effect->process)
- effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
- else
- effect->process(effect, bufferAudioIn, bufferAudioOut, bufferSize);
-#else
- CARLA_ASSERT(effect->flags & effFlagsCanReplacing);
- if (effect->flags & effFlagsCanReplacing)
- effect->processReplacing(effect, bufferAudioIn, bufferAudioOut, bufferSize);
-#endif
-
- effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
- effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
-
- for (int j=0; j < audioIns; j++)
- delete[] bufferAudioIn[j];
- for (int j=0; j < audioOuts; j++)
- delete[] bufferAudioOut[j];
- delete[] bufferAudioIn;
- delete[] bufferAudioOut;
- }
-
- // end crash-free plugin test
- // -----------------------------------------------------------------------
-
- DISCOVERY_OUT("init", "-----------");
- DISCOVERY_OUT("name", cName);
- DISCOVERY_OUT("label", cProduct);
- DISCOVERY_OUT("maker", cVendor);
- DISCOVERY_OUT("copyright", cVendor);
- DISCOVERY_OUT("unique_id", vstCurrentUniqueId);
- DISCOVERY_OUT("hints", hints);
- DISCOVERY_OUT("audio.ins", audioIns);
- DISCOVERY_OUT("audio.outs", audioOuts);
- DISCOVERY_OUT("audio.total", audioTotal);
- DISCOVERY_OUT("midi.ins", midiIns);
- DISCOVERY_OUT("midi.outs", midiOuts);
- DISCOVERY_OUT("midi.total", midiTotal);
- DISCOVERY_OUT("parameters.ins", parametersIns);
- DISCOVERY_OUT("parameters.total", parametersTotal);
- DISCOVERY_OUT("programs.total", programsTotal);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
-
- if (vstCategory != kPlugCategShell)
- break;
-
- strBuf[0] = 0;
- vstWantsMidi = false;
- vstCurrentUniqueId = effect->dispatcher(effect, effShellGetNextPlugin, 0, 0, strBuf, 0.0f);
-
- if (vstCurrentUniqueId != 0)
- {
- free((void*)cName);
- cName = strdup((strBuf[0] != 0) ? strBuf : "");
- }
- else
- break;
- }
-
- effect->dispatcher(effect, effClose, 0, 0, nullptr, 0.0f);
-
- free((void*)cName);
- free((void*)cProduct);
- free((void*)cVendor);
-#else
- DISCOVERY_OUT("error", "VST support not available");
- Q_UNUSED(libHandle);
- Q_UNUSED(init);
-#endif
-}
-
-void do_fluidsynth_check(const char* const filename, const bool init)
-{
-#ifdef WANT_FLUIDSYNTH
- if (! fluid_is_soundfont(filename))
- {
- DISCOVERY_OUT("error", "Not a SF2 file");
- return;
- }
-
- int programs = 0;
-
- if (init)
- {
- fluid_settings_t* const f_settings = new_fluid_settings();
- fluid_synth_t* const f_synth = new_fluid_synth(f_settings);
- const int f_id = fluid_synth_sfload(f_synth, filename, 0);
-
- if (f_id < 0)
- {
- DISCOVERY_OUT("error", "Failed to load SF2 file");
- return;
- }
-
- fluid_sfont_t* f_sfont;
- fluid_preset_t f_preset;
-
- f_sfont = fluid_synth_get_sfont_by_id(f_synth, f_id);
-
- f_sfont->iteration_start(f_sfont);
- while (f_sfont->iteration_next(f_sfont, &f_preset))
- programs += 1;
-
- delete_fluid_synth(f_synth);
- delete_fluid_settings(f_settings);
- }
-
- DISCOVERY_OUT("init", "-----------");
- DISCOVERY_OUT("name", "");
- DISCOVERY_OUT("label", "");
- DISCOVERY_OUT("maker", "");
- DISCOVERY_OUT("copyright", "");
- DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
- DISCOVERY_OUT("audio.outs", 2);
- DISCOVERY_OUT("audio.total", 2);
- DISCOVERY_OUT("midi.ins", 1);
- DISCOVERY_OUT("midi.total", 1);
- DISCOVERY_OUT("programs.total", programs);
- DISCOVERY_OUT("parameters.ins", 13); // defined in Carla
- DISCOVERY_OUT("parameters.outs", 1);
- DISCOVERY_OUT("parameters.total", 14);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
-#else
- DISCOVERY_OUT("error", "SF2 support not available");
- Q_UNUSED(filename);
- Q_UNUSED(init);
-#endif
-}
-
-void do_linuxsampler_check(const char* const filename, const char* const stype, const bool init)
-{
-#ifdef WANT_LINUXSAMPLER
- const QFileInfo file(filename);
-
- if (! file.exists())
- {
- DISCOVERY_OUT("error", "Requested file does not exist");
- return;
- }
-
- if (! file.isFile())
- {
- DISCOVERY_OUT("error", "Requested file is not valid");
- return;
- }
-
- if (! file.isReadable())
- {
- DISCOVERY_OUT("error", "Requested file is not readable");
- return;
- }
-
- using namespace LinuxSampler;
-
- class LinuxSamplerScopedEngine {
- public:
- LinuxSamplerScopedEngine(const char* const filename, const char* const stype)
- {
- engine = nullptr;
-
- try {
- engine = EngineFactory::Create(stype);
- }
- catch (const Exception& e)
- {
- DISCOVERY_OUT("error", e.what());
- return;
- }
-
- if (! engine)
- return;
-
- ins = engine->GetInstrumentManager();
-
- if (! ins)
- {
- DISCOVERY_OUT("error", "Failed to get LinuxSampler instrument manager");
- return;
- }
-
- std::vector ids;
-
- try {
- ids = ins->GetInstrumentFileContent(filename);
- }
- catch (const Exception& e)
- {
- DISCOVERY_OUT("error", e.what());
- return;
- }
-
- if (ids.size() > 0)
- {
- InstrumentManager::instrument_info_t info = ins->GetInstrumentInfo(ids[0]);
- outputInfo(&info, ids.size());
- }
- }
-
- ~LinuxSamplerScopedEngine()
- {
- if (engine)
- EngineFactory::Destroy(engine);
- }
-
- static void outputInfo(InstrumentManager::instrument_info_t* const info, const int programs, const char* const basename = nullptr)
- {
- DISCOVERY_OUT("init", "-----------");
-
- if (info)
- {
- DISCOVERY_OUT("name", info->InstrumentName);
- DISCOVERY_OUT("label", info->Product);
- DISCOVERY_OUT("maker", info->Artists);
- DISCOVERY_OUT("copyright", info->Artists);
- }
- else
- {
- DISCOVERY_OUT("name", basename);
- DISCOVERY_OUT("label", basename);
- }
-
- DISCOVERY_OUT("hints", PLUGIN_IS_SYNTH);
- DISCOVERY_OUT("audio.outs", 2);
- DISCOVERY_OUT("audio.total", 2);
- DISCOVERY_OUT("midi.ins", 1);
- DISCOVERY_OUT("midi.total", 1);
- DISCOVERY_OUT("programs.total", programs);
- //DISCOVERY_OUT("parameters.ins", 13); // defined in Carla - TODO
- //DISCOVERY_OUT("parameters.outs", 1);
- //DISCOVERY_OUT("parameters.total", 14);
- DISCOVERY_OUT("build", BINARY_NATIVE);
- DISCOVERY_OUT("end", "------------");
- }
-
- private:
- Engine* engine;
- InstrumentManager* ins;
- };
-
- if (init)
- const LinuxSamplerScopedEngine engine(filename, stype);
- else
- LinuxSamplerScopedEngine::outputInfo(nullptr, 0, file.baseName().toUtf8().constData());
-#else
- DISCOVERY_OUT("error", stype << " support not available");
- Q_UNUSED(filename);
- Q_UNUSED(init);
-#endif
-}
-
-// ------------------------------ main entry point ------------------------------
-
-int main(int argc, char* argv[])
-{
- if (argc == 2 && strcmp(argv[1], "-formats") == 0)
- {
- printf("Available plugin formats:\n");
- printf("LADSPA: ");
-#ifdef WANT_LADSPA
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("DSSI: ");
-#ifdef WANT_DSSI
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("LV2: ");
-#ifdef WANT_LV2
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("VST: ");
-#ifdef WANT_VST
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("\n");
-
- printf("Available sampler formats:\n");
- printf("GIG (LinuxSampler): ");
-#ifdef WANT_LINUXSAMPLER
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("SF2 (FluidSynth): ");
-#ifdef WANT_FLUIDSYNTH
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- printf("SFZ (LinuxSampler): ");
-#ifdef WANT_LINUXSAMPLER
- printf("yes\n");
-#else
- printf("no\n");
-#endif
- return 0;
- }
-
- if (argc != 3)
- {
- qWarning("usage: %s ", argv[0]);
- return 1;
- }
-
- const char* const stype = argv[1];
- const char* const filename = argv[2];
-
- bool openLib;
- PluginType type;
- void* handle = nullptr;
-
- if (strcmp(stype, "LADSPA") == 0)
- {
- openLib = true;
- type = PLUGIN_LADSPA;
- }
- else if (strcmp(stype, "DSSI") == 0)
- {
- openLib = true;
- type = PLUGIN_DSSI;
- }
- else if (strcmp(stype, "LV2") == 0)
- {
- openLib = false;
- type = PLUGIN_LV2;
- }
- else if (strcmp(stype, "VST") == 0)
- {
- openLib = true;
- type = PLUGIN_VST;
- }
- else if (strcmp(stype, "GIG") == 0)
- {
- openLib = false;
- type = PLUGIN_GIG;
- }
- else if (strcmp(stype, "SF2") == 0)
- {
- openLib = false;
- type = PLUGIN_SF2;
- }
- else if (strcmp(stype, "SFZ") == 0)
- {
- openLib = false;
- type = PLUGIN_SFZ;
- }
- else
- {
- DISCOVERY_OUT("error", "Invalid plugin type");
- return 1;
- }
-
- if (openLib)
- {
- handle = lib_open(filename);
-
- if (! handle)
- {
- print_lib_error(filename);
- return 1;
- }
- }
-
- bool doInit = ! QString(filename).endsWith("dssi-vst.so", Qt::CaseInsensitive);
-
- if (doInit && getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"))
- doInit = false;
-
- switch (type)
- {
- case PLUGIN_LADSPA:
- do_ladspa_check(handle, doInit);
- break;
- case PLUGIN_DSSI:
- do_dssi_check(handle, doInit);
- break;
- case PLUGIN_LV2:
- do_lv2_check(filename, doInit);
- break;
- case PLUGIN_VST:
- do_vst_check(handle, doInit);
- break;
- case PLUGIN_GIG:
- do_linuxsampler_check(filename, "gig", doInit);
- break;
- case PLUGIN_SF2:
- do_fluidsynth_check(filename, doInit);
- break;
- case PLUGIN_SFZ:
- do_linuxsampler_check(filename, "sfz", doInit);
- break;
- default:
- break;
- }
-
- if (openLib)
- lib_close(handle);
-
- return 0;
-}
diff --git a/c++/carla-discovery/carla-discovery.pro b/c++/carla-discovery/carla-discovery.pro
deleted file mode 100644
index 4c4f6fc..0000000
--- a/c++/carla-discovery/carla-discovery.pro
+++ /dev/null
@@ -1,35 +0,0 @@
-# QtCreator project file
-
-QT = core
-
-CONFIG = debug
-CONFIG += link_pkgconfig qt warn_on
-
-DEFINES = DEBUG
-DEFINES += WANT_LADSPA WANT_DSSI WANT_LV2 WANT_VST
-DEFINES += WANT_FLUIDSYNTH WANT_LINUXSAMPLER
-PKGCONFIG = fluidsynth linuxsampler
-
-TARGET = carla-discovery-native
-TEMPLATE = app
-VERSION = 0.5.0
-
-SOURCES = \
- carla-discovery.cpp
-
-INCLUDEPATH = \
- ../carla-backend \
- ../carla-includes \
- ../carla-utils
-
-LIBS = \
- ../carla-lilv/carla_lilv.a
-
-unix {
-LIBS += -ldl -lpthread
-}
-win {
-LIBS += -static -mwindows
-}
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-engine/DistrhoPluginInfo.h b/c++/carla-engine/DistrhoPluginInfo.h
deleted file mode 100644
index 2ab1049..0000000
--- a/c++/carla-engine/DistrhoPluginInfo.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Carla Plugin Engine
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef __DISTRHO_PLUGIN_INFO_H__
-#define __DISTRHO_PLUGIN_INFO_H__
-
-#define DISTRHO_PLUGIN_NAME "Carla"
-
-#define DISTRHO_PLUGIN_HAS_UI 0
-#define DISTRHO_PLUGIN_IS_SYNTH 1
-
-#define DISTRHO_PLUGIN_NUM_INPUTS 2
-#define DISTRHO_PLUGIN_NUM_OUTPUTS 2
-
-#define DISTRHO_PLUGIN_WANT_LATENCY 1
-#define DISTRHO_PLUGIN_WANT_PROGRAMS 1
-#define DISTRHO_PLUGIN_WANT_STATE 1
-
-#define DISTRHO_PLUGIN_URI "http://kxstudio.sf.net/carla"
-
-#endif // __DISTRHO_PLUGIN_INFO_H__
diff --git a/c++/carla-engine/Makefile b/c++/carla-engine/Makefile
deleted file mode 100644
index 9f4aebc..0000000
--- a/c++/carla-engine/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/make -f
-# Makefile for carla-engine #
-# ------------------------------------ #
-# Created by falkTX
-#
-
-include ../Makefile.mk
-
-# --------------------------------------------------------------
-
-BUILD_CXX_FLAGS += -fvisibility=hidden -fPIC
-BUILD_CXX_FLAGS += -I. -I../carla-backend -I../carla-includes -I../carla-plugin -I../carla-utils
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags liblo QtCore)
-
-ifeq ($(CARLA_PLUGIN_SUPPORT),true)
-BUILD_CXX_FLAGS += -DWANT_LV2
-endif
-
-ifeq ($(HAVE_JACK),true)
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags jack) -D__UNIX_JACK__
-WANT_JACK = true
-endif
-
-ifeq ($(HAVE_ALSA),true)
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags alsa) -D__LINUX_ALSA__ -D__LINUX_ALSASEQ__
-WANT_RTAUDIO = true
-endif
-
-ifeq ($(HAVE_PULSEAUDIO),true)
-BUILD_CXX_FLAGS += $(shell pkg-config --cflags libpulse-simple) -D__LINUX_PULSE__
-WANT_RTAUDIO = true
-endif
-
-OBJS = \
- carla_engine.o \
- carla_engine_osc.o \
- carla_engine_thread.o \
- jack.o \
- rtaudio.o
-
-# --------------------------------------------------------------
-
-ifeq ($(WANT_JACK),true)
-BUILD_CXX_FLAGS += -DCARLA_ENGINE_JACK
-BUILD_CXX_FLAGS += -I../carla-jackbridge
-endif
-
-ifeq ($(WANT_RTAUDIO),true)
-BUILD_CXX_FLAGS += -DCARLA_ENGINE_RTAUDIO -DHAVE_GETTIMEOFDAY -D_FORTIFY_SOURCE=2
-BUILD_CXX_FLAGS += -Irtaudio-4.0.11 -Irtmidi-2.0.1
-ifeq ($(DEBUG),true)
-BUILD_CXX_FLAGS += -D__RTAUDIO_DEBUG__ -D__RTMIDI_DEBUG__
-endif
-OBJS += rtaudio-4.0.11/RtAudio.o
-OBJS += rtmidi-2.0.1/RtMidi.o
-endif
-
-# --------------------------------------------------------------
-
-all: carla_engine.a
-
-doxygen: carla_engine.doxygen
- doxygen $<
-
-carla_engine.a: $(OBJS)
- $(AR) rs $@ $^
-
-# --------------------------------------------------------------
-
-.cpp.o:
- $(CXX) -c $< $(BUILD_CXX_FLAGS) -o $@
-
-clean:
- rm -f *.a $(OBJS)
diff --git a/c++/carla-engine/carla_engine.cpp b/c++/carla-engine/carla_engine.cpp
deleted file mode 100644
index 5575420..0000000
--- a/c++/carla-engine/carla_engine.cpp
+++ /dev/null
@@ -1,1930 +0,0 @@
-/*
- * Carla Engine
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_engine.hpp"
-#include "carla_plugin.hpp"
-
-CARLA_BACKEND_START_NAMESPACE
-
-// -------------------------------------------------------------------------------------------------------------------
-// Utils
-
-const char* CarlaEngineType2Str(const CarlaEngineType type)
-{
- switch (type)
- {
- case CarlaEngineTypeNull:
- return "CarlaEngineTypeNull";
- case CarlaEngineTypeJack:
- return "CarlaEngineTypeJack";
- case CarlaEngineTypeRtAudio:
- return "CarlaEngineTypeRtAudio";
- case CarlaEngineTypePlugin:
- return "CarlaEngineTypePlugin";
- }
-
- qWarning("CarlaBackend::CarlaEngineType2Str(%i) - invalid type", type);
- return nullptr;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (Base)
-
-CarlaEngineBasePort::CarlaEngineBasePort(const bool isInput_, const ProcessMode processMode_)
- : isInput(isInput_),
- processMode(processMode_)
-{
- qDebug("CarlaEngineBasePort::CarlaEngineBasePort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-
- buffer = nullptr;
-}
-
-CarlaEngineBasePort::~CarlaEngineBasePort()
-{
- qDebug("CarlaEngineBasePort::~CarlaEngineBasePort()");
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (Audio)
-
-CarlaEngineAudioPort::CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode)
- : CarlaEngineBasePort(isInput, processMode)
-{
- qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-}
-
-CarlaEngineAudioPort::~CarlaEngineAudioPort()
-{
- qDebug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
-}
-
-void CarlaEngineAudioPort::initBuffer(CarlaEngine* const)
-{
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (Control)
-
-CarlaEngineControlPort::CarlaEngineControlPort(const bool isInput, const ProcessMode processMode)
- : CarlaEngineBasePort(isInput, processMode)
-{
- qDebug("CarlaEngineControlPort::CarlaEngineControlPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-}
-
-CarlaEngineControlPort::~CarlaEngineControlPort()
-{
- qDebug("CarlaEngineControlPort::~CarlaEngineControlPort()");
-}
-
-void CarlaEngineControlPort::initBuffer(CarlaEngine* const engine)
-{
- CARLA_ASSERT(engine);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- buffer = isInput ? engine->rackControlEventsIn : engine->rackControlEventsOut;
-#endif
-}
-
-uint32_t CarlaEngineControlPort::getEventCount()
-{
- if (! isInput)
- return 0;
-
- CARLA_ASSERT(buffer);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- uint32_t count = 0;
- const CarlaEngineControlEvent* const events = (CarlaEngineControlEvent*)buffer;
-
- for (unsigned short i=0; i < CarlaEngine::MAX_CONTROL_EVENTS; i++, count++)
- {
- if (events[i].type == CarlaEngineNullEvent)
- break;
- }
-
- return count;
- }
-#endif
-
- return 0;
-}
-
-const CarlaEngineControlEvent* CarlaEngineControlPort::getEvent(const uint32_t index)
-{
- if (! isInput)
- return nullptr;
-
- CARLA_ASSERT(buffer);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- CARLA_ASSERT(index < CarlaEngine::MAX_CONTROL_EVENTS);
-
- const CarlaEngineControlEvent* const events = (CarlaEngineControlEvent*)buffer;
-
- if (index < CarlaEngine::MAX_CONTROL_EVENTS)
- return &events[index];
- }
-#else
- Q_UNUSED(index);
-#endif
-
- return nullptr;
-}
-
-void CarlaEngineControlPort::writeEvent(const CarlaEngineControlEventType type, const uint32_t time, const uint8_t channel, const uint16_t parameter, const double value)
-{
- if (isInput)
- return;
-
- CARLA_ASSERT(buffer);
- CARLA_ASSERT(type != CarlaEngineNullEvent);
-
- if (type == CarlaEngineNullEvent)
- return;
- if (type == CarlaEngineParameterChangeEvent)
- CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter));
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- CarlaEngineControlEvent* const events = (CarlaEngineControlEvent*)buffer;
-
- for (unsigned short i=0; i < CarlaEngine::MAX_CONTROL_EVENTS; i++)
- {
- if (events[i].type != CarlaEngineNullEvent)
- continue;
-
- events[i].type = type;
- events[i].time = time;
- events[i].value = value;
- events[i].channel = channel;
- events[i].parameter = parameter;
- break;
- }
-
- qWarning("CarlaEngineControlPort::writeEvent() - buffer full");
- }
-#else
- Q_UNUSED(time);
- Q_UNUSED(channel);
- Q_UNUSED(parameter);
- Q_UNUSED(value);
-#endif
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (MIDI)
-
-CarlaEngineMidiPort::CarlaEngineMidiPort(const bool isInput, const ProcessMode processMode)
- : CarlaEngineBasePort(isInput, processMode)
-{
- qDebug("CarlaEngineMidiPort::CarlaEngineMidiPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-}
-
-CarlaEngineMidiPort::~CarlaEngineMidiPort()
-{
- qDebug("CarlaEngineMidiPort::~CarlaEngineMidiPort()");
-}
-
-void CarlaEngineMidiPort::initBuffer(CarlaEngine* const engine)
-{
- CARLA_ASSERT(engine);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- buffer = isInput ? engine->rackMidiEventsIn : engine->rackMidiEventsOut;
-#endif
-}
-
-uint32_t CarlaEngineMidiPort::getEventCount()
-{
- if (! isInput)
- return 0;
-
- CARLA_ASSERT(buffer);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- uint32_t count = 0;
- const CarlaEngineMidiEvent* const events = (CarlaEngineMidiEvent*)buffer;
-
- for (unsigned short i=0; i < CarlaEngine::MAX_MIDI_EVENTS; i++, count++)
- {
- if (events[i].size == 0)
- break;
- }
-
- return count;
- }
-#endif
-
- return 0;
-}
-
-const CarlaEngineMidiEvent* CarlaEngineMidiPort::getEvent(uint32_t index)
-{
- if (! isInput)
- return nullptr;
-
- CARLA_ASSERT(buffer);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- CARLA_ASSERT(index < CarlaEngine::MAX_MIDI_EVENTS);
-
- const CarlaEngineMidiEvent* const events = (CarlaEngineMidiEvent*)buffer;
-
- if (index < CarlaEngine::MAX_MIDI_EVENTS)
- return &events[index];
- }
-#else
- Q_UNUSED(index);
-#endif
-
- return nullptr;
-}
-
-void CarlaEngineMidiPort::writeEvent(const uint32_t time, const uint8_t* const data, const uint8_t size)
-{
- if (isInput)
- return;
-
- CARLA_ASSERT(buffer);
- CARLA_ASSERT(data);
- CARLA_ASSERT(size > 0);
-
-#ifndef BUILD_BRIDGE
- if (processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- if (size > 4)
- return;
-
- CarlaEngineMidiEvent* const events = (CarlaEngineMidiEvent*)buffer;
-
- for (unsigned short i=0; i < CarlaEngine::MAX_MIDI_EVENTS; i++)
- {
- if (events[i].size != 0)
- continue;
-
- events[i].time = time;
- events[i].size = size;
- memcpy(events[i].data, data, size);
- break;
- }
-
- qWarning("CarlaEngineMidiPort::writeEvent() - buffer full");
- }
-#else
- Q_UNUSED(time);
-#endif
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Carla Engine Client
-
-CarlaEngineClient::CarlaEngineClient(const CarlaEngineType engineType_, const ProcessMode processMode_)
- : engineType(engineType_),
- processMode(processMode_)
-{
- qDebug("CarlaEngineClient::CarlaEngineClient(%s, %s)", CarlaEngineType2Str(engineType), ProcessMode2Str(processMode));
- CARLA_ASSERT(engineType != CarlaEngineTypeNull);
-
- m_active = false;
- m_latency = 0;
-}
-
-CarlaEngineClient::~CarlaEngineClient()
-{
- qDebug("CarlaEngineClient::~CarlaEngineClient()");
- CARLA_ASSERT(! m_active);
-}
-
-void CarlaEngineClient::activate()
-{
- qDebug("CarlaEngineClient::activate()");
- CARLA_ASSERT(! m_active);
-
- m_active = true;
-}
-
-void CarlaEngineClient::deactivate()
-{
- qDebug("CarlaEngineClient::deactivate()");
- CARLA_ASSERT(m_active);
-
- m_active = false;
-}
-
-bool CarlaEngineClient::isActive() const
-{
- qDebug("CarlaEngineClient::isActive()");
-
- return m_active;
-}
-
-bool CarlaEngineClient::isOk() const
-{
- qDebug("CarlaEngineClient::isOk()");
-
- return true;
-}
-
-uint32_t CarlaEngineClient::getLatency() const
-{
- return m_latency;
-}
-
-void CarlaEngineClient::setLatency(const uint32_t samples)
-{
- m_latency = samples;
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Carla Engine Client
-
-CarlaEngine::CarlaEngine()
- : m_osc(this),
- m_thread(this),
- m_callbackPtr(nullptr),
- m_carlaPlugins{nullptr},
- m_uniqueNames{nullptr},
- m_insPeak{0.0},
- m_outsPeak{0.0}
-{
- qDebug("CarlaEngine::CarlaEngine()");
-
- bufferSize = 0;
- sampleRate = 0.0;
-
- m_oscData = nullptr;
- m_callback = nullptr;
- m_callbackPtr = nullptr;
-
- m_aboutToClose = false;
- m_maxPluginNumber = 0;
-}
-
-CarlaEngine::~CarlaEngine()
-{
- qDebug("CarlaEngine::~CarlaEngine()");
-}
-
-// -----------------------------------------------------------------------
-// Static values and calls
-
-unsigned int CarlaEngine::getDriverCount()
-{
- unsigned int count = 0;
-#ifdef CARLA_ENGINE_JACK
- count += 1;
-#endif
-#ifdef CARLA_ENGINE_RTAUDIO
- count += getRtAudioApiCount();
-#endif
- return count;
-}
-
-const char* CarlaEngine::getDriverName(unsigned int index)
-{
-#ifdef CARLA_ENGINE_JACK
- if (index == 0)
- return "JACK";
- else
- index -= 1;
-#endif
-
-#ifdef CARLA_ENGINE_RTAUDIO
- if (index < getRtAudioApiCount())
- return getRtAudioApiName(index);
-#endif
-
- qWarning("CarlaEngine::getDriverName(%i) - invalid index", index);
- return nullptr;
-}
-
-CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
-{
-#ifdef CARLA_ENGINE_JACK
- if (strcmp(driverName, "JACK") == 0)
- return newJack();
-#else
- if (false)
- pass();
-#endif
-
-#ifdef CARLA_ENGINE_RTAUDIO
-# ifdef __LINUX_ALSA__
- else if (strcmp(driverName, "ALSA") == 0)
- return newRtAudio(RTAUDIO_LINUX_ALSA);
-# endif
-# ifdef __LINUX_PULSE__
- else if (strcmp(driverName, "PulseAudio") == 0)
- return newRtAudio(RTAUDIO_LINUX_PULSE);
-# endif
-# ifdef __LINUX_OSS__
- else if (strcmp(driverName, "OSS") == 0)
- return newRtAudio(RTAUDIO_LINUX_OSS);
-# endif
-# ifdef __UNIX_JACK__
- else if (strcmp(driverName, "JACK (RtAudio)") == 0)
- return newRtAudio(RTAUDIO_UNIX_JACK);
-# endif
-# ifdef __MACOSX_CORE__
- else if (strcmp(driverName, "CoreAudio") == 0)
- return newRtAudio(RTAUDIO_MACOSX_CORE);
-# endif
-# ifdef __WINDOWS_ASIO__
- else if (strcmp(driverName, "ASIO") == 0)
- return newRtAudio(RTAUDIO_WINDOWS_ASIO);
-# endif
-# ifdef __WINDOWS_DS__
- else if (strcmp(driverName, "DirectSound") == 0)
- return newRtAudio(RTAUDIO_WINDOWS_DS);
-# endif
-#endif
-
- return nullptr;
-}
-
-// -----------------------------------------------------------------------
-// Maximum values
-
-int CarlaEngine::maxClientNameSize()
-{
- return STR_MAX/2;
-}
-
-int CarlaEngine::maxPortNameSize()
-{
- return STR_MAX;
-}
-
-unsigned short CarlaEngine::maxPluginNumber() const
-{
- return m_maxPluginNumber;
-}
-
-// -----------------------------------------------------------------------
-// Virtual, per-engine type calls
-
-bool CarlaEngine::init(const char* const clientName)
-{
- qDebug("CarlaEngine::init(\"%s\")", clientName);
-
- m_aboutToClose = false;
-
- m_osc.init(clientName);
-
-#ifndef BUILD_BRIDGE
- m_oscData = m_osc.getControlData();
-
- if (strcmp(clientName, "Carla") != 0)
- carla_setprocname(clientName);
-#endif
-
- m_thread.startNow();
-
- return true;
-}
-
-bool CarlaEngine::close()
-{
- qDebug("CarlaEngine::close()");
-
- m_aboutToClose = true;
- m_thread.stopNow();
-
-#ifndef BUILD_BRIDGE
- osc_send_control_exit();
-#endif
- m_osc.close();
-
- m_oscData = nullptr;
- m_maxPluginNumber = 0;
-
- name.clear();
-
- return true;
-}
-
-// -----------------------------------------------------------------------
-// Plugin management
-
-short CarlaEngine::getNewPluginId() const
-{
- qDebug("CarlaEngine::getNewPluginId()");
-
- for (unsigned short i=0; i < m_maxPluginNumber; i++)
- {
- if (! m_carlaPlugins[i])
- return i;
- }
-
- return -1;
-}
-
-CarlaPlugin* CarlaEngine::getPlugin(const unsigned short id) const
-{
- qDebug("CarlaEngine::getPlugin(%i/%i)", id, m_maxPluginNumber);
- CARLA_ASSERT(m_maxPluginNumber != 0);
- CARLA_ASSERT(id < m_maxPluginNumber);
-
- if (id < m_maxPluginNumber)
- return m_carlaPlugins[id];
-
- return nullptr;
-}
-
-CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned short id) const
-{
- CARLA_ASSERT(m_maxPluginNumber != 0);
- CARLA_ASSERT(id < m_maxPluginNumber);
-
- return m_carlaPlugins[id];
-}
-
-const char* CarlaEngine::getUniquePluginName(const char* const name)
-{
- qDebug("CarlaEngine::getUniquePluginName(\"%s\")", name);
- CARLA_ASSERT(name);
-
- CarlaString sname(name);
-
- if (sname.isEmpty())
- sname = "(No name)";
-
- sname.truncate(maxClientNameSize()-5-1); // 5 = strlen(" (10)")
- sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names
-
- for (unsigned short i=0; i < m_maxPluginNumber; i++)
- {
- // Check if unique name already exists
- if (m_uniqueNames[i] && sname == m_uniqueNames[i])
- {
- // Check if string has already been modified
- size_t len = sname.length();
-
- // 1 digit, ex: " (2)"
- if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')')
- {
- int number = sname[len-2]-'0';
-
- if (number == 9)
- {
- // next number is 10, 2 digits
- sname.truncate(len-4);
- sname += " (10)";
- //sname.replace(" (9)", " (10)");
- }
- else
- sname[len-2] = '0'+number+1;
-
- continue;
- }
-
- // 2 digits, ex: " (11)"
- if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')')
- {
- char n2 = sname[len-2];
- char n3 = sname[len-3];
-
- if (n2 == '9')
- {
- n2 = '0';
- n3 = n3+1;
- }
- else
- n2 = n2+1;
-
- sname[len-2] = n2;
- sname[len-3] = n3;
-
- continue;
- }
-
- // Modify string if not
- sname += " (2)";
- }
- }
-
- return strdup(sname);
-}
-
-short CarlaEngine::addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra)
-{
- return addPlugin(BINARY_NATIVE, ptype, filename, name, label, extra);
-}
-
-short CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra)
-{
- qDebug("CarlaEngine::addPlugin(%s, %s, \"%s\", \"%s\", \"%s\", %p)", BinaryType2Str(btype), PluginType2Str(ptype), filename, name, label, extra);
- CARLA_ASSERT(btype != BINARY_NONE);
- CARLA_ASSERT(ptype != PLUGIN_NONE);
- CARLA_ASSERT(filename);
- CARLA_ASSERT(label);
-
- if (m_maxPluginNumber == 0)
- {
-#ifdef BUILD_BRIDGE
- m_maxPluginNumber = MAX_PLUGINS;
-#else
- m_maxPluginNumber = (options.processMode == PROCESS_MODE_CONTINUOUS_RACK) ? 16 : MAX_PLUGINS;
-#endif
- }
-
- CarlaPlugin::initializer init = {
- this,
- filename,
- name,
- label
- };
-
- CarlaPlugin* plugin = nullptr;
-
-#ifndef BUILD_BRIDGE
- if (btype != BINARY_NATIVE || (options.preferPluginBridges && extra /* extra = bridgeBinary */ && type() == CarlaEngineTypeJack))
- {
-# ifdef CARLA_ENGINE_JACK
- if (options.processMode != CarlaBackend::PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- setLastError("Can only use bridged plugins in JACK Multi-Client mode");
- return -1;
- }
-# endif
-
- if (type() != CarlaEngineTypeJack)
- {
- setLastError("Can only use bridged plugins with JACK backend");
- return -1;
- }
-
- plugin = CarlaPlugin::newBridge(init, btype, ptype, extra);
- }
- else
-#endif
- {
- switch (ptype)
- {
- case PLUGIN_NONE:
- break;
-#ifndef BUILD_BRIDGE
- case PLUGIN_INTERNAL:
- plugin = CarlaPlugin::newNative(init);
- break;
-#endif
- case PLUGIN_LADSPA:
- plugin = CarlaPlugin::newLADSPA(init, extra);
- break;
- case PLUGIN_DSSI:
- plugin = CarlaPlugin::newDSSI(init, extra);
- break;
- case PLUGIN_LV2:
- plugin = CarlaPlugin::newLV2(init);
- break;
- case PLUGIN_VST:
- plugin = CarlaPlugin::newVST(init);
- break;
-#ifndef BUILD_BRIDGE
- case PLUGIN_GIG:
- plugin = CarlaPlugin::newGIG(init);
- break;
- case PLUGIN_SF2:
- plugin = CarlaPlugin::newSF2(init);
- break;
- case PLUGIN_SFZ:
- plugin = CarlaPlugin::newSFZ(init);
- break;
-#else
- default:
- break;
-#endif
- }
- }
-
- if (! plugin)
- return -1;
-
- const short id = plugin->id();
-
- m_carlaPlugins[id] = plugin;
- m_uniqueNames[id] = plugin->name();
-
- return id;
-}
-
-bool CarlaEngine::removePlugin(const unsigned short id)
-{
- qDebug("CarlaEngine::removePlugin(%i)", id);
- CARLA_ASSERT(m_maxPluginNumber != 0);
- CARLA_ASSERT(id < m_maxPluginNumber);
-
- CarlaPlugin* const plugin = m_carlaPlugins[id];
-
- if (plugin /*&& plugin->id() == id*/)
- {
- CARLA_ASSERT(plugin->id() == id);
-
- m_thread.stopNow();
-
- processLock();
- plugin->setEnabled(false);
- m_carlaPlugins[id] = nullptr;
- m_uniqueNames[id] = nullptr;
- processUnlock();
-
- delete plugin;
-
-#ifndef BUILD_BRIDGE
- osc_send_control_remove_plugin(id);
-
- if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- // TODO - handle OSC server comm
-
- for (unsigned short i=id; i < m_maxPluginNumber-1; i++)
- {
- m_carlaPlugins[i] = m_carlaPlugins[i+1];
- m_uniqueNames[i] = m_uniqueNames[i+1];
-
- if (m_carlaPlugins[i])
- m_carlaPlugins[i]->setId(i);
- }
- }
-#endif
-
- if (isRunning() && ! m_aboutToClose)
- m_thread.startNow();
-
- return true;
- }
-
- qCritical("CarlaEngine::removePlugin(%i) - could not find plugin", id);
- setLastError("Could not find plugin to remove");
- return false;
-}
-
-void CarlaEngine::removeAllPlugins()
-{
- qDebug("CarlaEngine::removeAllPlugins()");
-
- m_thread.stopNow();
-
- for (unsigned short i=0; i < m_maxPluginNumber; i++)
- {
- CarlaPlugin* const plugin = m_carlaPlugins[i];
-
- if (plugin)
- {
- processLock();
- plugin->setEnabled(false);
- processUnlock();
-
- delete plugin;
- m_carlaPlugins[i] = nullptr;
- m_uniqueNames[i] = nullptr;
- }
- }
-
- m_maxPluginNumber = 0;
-
- if (isRunning() && ! m_aboutToClose)
- m_thread.startNow();
-}
-
-void CarlaEngine::idlePluginGuis()
-{
- CARLA_ASSERT(m_maxPluginNumber != 0);
-
- for (unsigned short i=0; i < m_maxPluginNumber; i++)
- {
- CarlaPlugin* const plugin = m_carlaPlugins[i];
-
- if (plugin && plugin->enabled())
- plugin->idleGui();
- }
-}
-
-#ifndef BUILD_BRIDGE
-void CarlaEngine::processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames)
-{
- // initialize outputs (zero)
- carla_zeroF(outBuf[0], frames);
- carla_zeroF(outBuf[1], frames);
- memset(rackControlEventsOut, 0, sizeof(CarlaEngineControlEvent)*MAX_CONTROL_EVENTS);
- memset(rackMidiEventsOut, 0, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
-
- bool processed = false;
-
- // process plugins
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-
- if (plugin && plugin->enabled())
- {
- 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);
-
- // initialize outputs (zero)
- carla_zeroF(outBuf[0], frames);
- carla_zeroF(outBuf[1], frames);
- memset(rackMidiEventsOut, 0, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
- }
-
- // process
- processLock();
- plugin->initBuffers();
-
- if (plugin->m_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();
-
- // if plugin has no audio inputs, add previous buffers
- if (plugin->audioInCount() == 0)
- {
- for (uint32_t j=0; j < frames; j++)
- {
- outBuf[0][j] += inBuf[0][j];
- outBuf[1][j] += inBuf[1][j];
- }
- }
-
- // if plugin has no midi output, add previous midi input
- if (plugin->midiOutCount() == 0)
- {
- memcpy(rackMidiEventsOut, rackMidiEventsIn, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
- }
-
- // set peaks
- {
- double inPeak1 = 0.0;
- double inPeak2 = 0.0;
- double outPeak1 = 0.0;
- double outPeak2 = 0.0;
-
- for (uint32_t k=0; k < frames; k++)
- {
- 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]);
- }
-
- m_insPeak[i*MAX_PEAKS + 0] = inPeak1;
- m_insPeak[i*MAX_PEAKS + 1] = inPeak2;
- m_outsPeak[i*MAX_PEAKS + 0] = outPeak1;
- m_outsPeak[i*MAX_PEAKS + 1] = outPeak2;
- }
-
- processed = true;
- }
- }
-
- // if no plugins in the rack, copy inputs over outputs
- if (! processed)
- {
- memcpy(outBuf[0], inBuf[0], sizeof(float)*frames);
- memcpy(outBuf[1], inBuf[1], sizeof(float)*frames);
- memcpy(rackMidiEventsOut, rackMidiEventsIn, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
- }
-}
-#endif
-
-// -----------------------------------------------------------------------
-// Information (base)
-
-const char* CarlaEngine::getName() const
-{
- CARLA_ASSERT(name);
- return name;
-}
-
-double CarlaEngine::getSampleRate() const
-{
- CARLA_ASSERT(sampleRate != 0.0);
- return sampleRate;
-}
-
-uint32_t CarlaEngine::getBufferSize() const
-{
- CARLA_ASSERT(bufferSize != 0);
- return bufferSize;
-}
-
-const CarlaEngineTimeInfo* CarlaEngine::getTimeInfo() const
-{
- return &timeInfo;
-}
-
-void CarlaEngine::aboutToClose()
-{
- qDebug("CarlaEngine::aboutToClose()");
- m_aboutToClose = true;
-}
-
-// -----------------------------------------------------------------------
-// Information (audio peaks)
-
-double CarlaEngine::getInputPeak(const unsigned short pluginId, const unsigned short id) const
-{
- CARLA_ASSERT(pluginId < m_maxPluginNumber);
- CARLA_ASSERT(id < MAX_PEAKS);
-
- return m_insPeak[pluginId*MAX_PEAKS + id];
-}
-
-double CarlaEngine::getOutputPeak(const unsigned short pluginId, const unsigned short id) const
-{
- CARLA_ASSERT(pluginId < m_maxPluginNumber);
- CARLA_ASSERT(id < MAX_PEAKS);
-
- return m_outsPeak[pluginId*MAX_PEAKS + id];
-}
-
-void CarlaEngine::setInputPeak(const unsigned short pluginId, const unsigned short id, double value)
-{
- CARLA_ASSERT(pluginId < m_maxPluginNumber);
- CARLA_ASSERT(id < MAX_PEAKS);
-
- m_insPeak[pluginId*MAX_PEAKS + id] = value;
-}
-
-void CarlaEngine::setOutputPeak(const unsigned short pluginId, const unsigned short id, double value)
-{
- CARLA_ASSERT(pluginId < m_maxPluginNumber);
- CARLA_ASSERT(id < MAX_PEAKS);
-
- m_outsPeak[pluginId*MAX_PEAKS + id] = value;
-}
-
-// -----------------------------------------------------------------------
-// Callback
-
-void CarlaEngine::callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3, const char* const valueStr)
-{
- qDebug("CarlaEngine::callback(%s, %i, %i, %i, %f, \"%s\")", CallbackType2Str(action), pluginId, value1, value2, value3, valueStr);
-
- if (m_callback)
- m_callback(m_callbackPtr, action, pluginId, value1, value2, value3, valueStr);
-}
-
-void CarlaEngine::setCallback(const CallbackFunc func, void* const ptr)
-{
- qDebug("CarlaEngine::setCallback(%p, %p)", func, ptr);
- CARLA_ASSERT(func);
-
- m_callback = func;
- m_callbackPtr = ptr;
-}
-
-// -----------------------------------------------------------------------
-// Error handling
-
-const char* CarlaEngine::getLastError() const
-{
- return m_lastError;
-}
-
-void CarlaEngine::setLastError(const char* const error)
-{
- m_lastError = error;
-}
-
-// -----------------------------------------------------------------------
-// Global options
-
-#ifndef BUILD_BRIDGE
-
-#define CARLA_ENGINE_SET_OPTION_RUNNING_CHECK \
- if (isRunning()) \
- return qCritical("CarlaEngine::setOption(%s, %i, \"%s\") - Cannot set this option while engine is running!", OptionsType2Str(option), value, valueStr);
-
-void CarlaEngine::setOption(const OptionsType option, const int value, const char* const valueStr)
-{
- qDebug("CarlaEngine::setOption(%s, %i, \"%s\")", OptionsType2Str(option), value, valueStr);
-
- switch (option)
- {
- case OPTION_PROCESS_NAME:
- carla_setprocname(valueStr);
- break;
-
- case OPTION_PROCESS_MODE:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
-
- if (value < PROCESS_MODE_SINGLE_CLIENT || value > PROCESS_MODE_PATCHBAY)
- return qCritical("CarlaEngine::setOption(%s, %i, \"%s\") - invalid value", OptionsType2Str(option), value, valueStr);
-
- options.processMode = static_cast(value);
- break;
-
- case OPTION_PROCESS_HIGH_PRECISION:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.processHighPrecision = value;
- break;
-
- case OPTION_MAX_PARAMETERS:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.maxParameters = (value > 0) ? value : MAX_PARAMETERS;
- break;
-
- case OPTION_PREFERRED_BUFFER_SIZE:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.preferredBufferSize = value;
- break;
-
- case OPTION_PREFERRED_SAMPLE_RATE:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.preferredSampleRate = value;
- break;
-
- case OPTION_FORCE_STEREO:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.forceStereo = value;
- break;
-
- case OPTION_USE_DSSI_VST_CHUNKS:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.useDssiVstChunks = value;
- break;
-
- case OPTION_PREFER_PLUGIN_BRIDGES:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.preferPluginBridges = value;
- break;
-
- case OPTION_PREFER_UI_BRIDGES:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.preferUiBridges = value;
- break;
-
- case OPTION_OSC_UI_TIMEOUT:
- CARLA_ENGINE_SET_OPTION_RUNNING_CHECK
- options.oscUiTimeout = value;
- break;
-
- case OPTION_PATH_BRIDGE_POSIX32:
- options.bridge_posix32 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_POSIX64:
- options.bridge_posix64 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_WIN32:
- options.bridge_win32 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_WIN64:
- options.bridge_win64 = valueStr;
- break;
-
- case OPTION_PATH_BRIDGE_LV2_GTK2:
- options.bridge_lv2gtk2 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_GTK3:
- options.bridge_lv2gtk3 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_QT4:
- options.bridge_lv2qt4 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_QT5:
- options.bridge_lv2qt5 = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_COCOA:
- options.bridge_lv2cocoa = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_WINDOWS:
- options.bridge_lv2win = valueStr;
- break;
- case OPTION_PATH_BRIDGE_LV2_X11:
- options.bridge_lv2x11 = valueStr;
- break;
-
- case OPTION_PATH_BRIDGE_VST_COCOA:
- options.bridge_vstcocoa = valueStr;
- break;
- case OPTION_PATH_BRIDGE_VST_HWND:
- options.bridge_vsthwnd = valueStr;
- break;
- case OPTION_PATH_BRIDGE_VST_X11:
- options.bridge_vstx11 = valueStr;
- break;
- }
-}
-#endif
-
-// -----------------------------------------------------------------------
-// Mutex locks
-
-void CarlaEngine::processLock()
-{
- m_procLock.lock();
-}
-
-void CarlaEngine::processTryLock()
-{
- m_procLock.tryLock();
-}
-
-void CarlaEngine::processUnlock()
-{
- m_procLock.unlock();
-}
-
-void CarlaEngine::midiLock()
-{
- m_midiLock.lock();
-}
-
-void CarlaEngine::midiTryLock()
-{
- m_midiLock.tryLock();
-}
-
-void CarlaEngine::midiUnlock()
-{
- m_midiLock.unlock();
-}
-
-// -----------------------------------------------------------------------
-// OSC Stuff
-
-#ifndef BUILD_BRIDGE
-bool CarlaEngine::isOscControlRegistered() const
-{
- return m_osc.isControlRegistered();
-}
-#else
-bool CarlaEngine::isOscBridgeRegistered() const
-{
- return bool(m_oscData);
-}
-#endif
-
-void CarlaEngine::idleOsc()
-{
- m_osc.idle();
-}
-
-const char* CarlaEngine::getOscServerPathTCP() const
-{
- return m_osc.getServerPathTCP();
-}
-
-const char* CarlaEngine::getOscServerPathUDP() const
-{
- return m_osc.getServerPathUDP();
-}
-
-#ifdef BUILD_BRIDGE
-void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData)
-{
- m_oscData = oscData;
-}
-#endif
-
-// -----------------------------------------------------------------------
-// protected calls
-
-void CarlaEngine::bufferSizeChanged(const uint32_t newBufferSize)
-{
- qDebug("CarlaEngine::bufferSizeChanged(%i)", newBufferSize);
-
- for (unsigned short i=0; i < m_maxPluginNumber; i++)
- {
- if (m_carlaPlugins[i] && m_carlaPlugins[i]->enabled() && ! m_carlaPlugins[i]->m_processHighPrecision)
- m_carlaPlugins[i]->bufferSizeChanged(newBufferSize);
- }
-}
-
-// -------------------------------------------------------------------------------------------------------------------
-// Carla Engine OSC stuff
-
-#ifdef BUILD_BRIDGE
-void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin)
-#else
-void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id)
-#endif
-{
- // Peak values
- if (plugin->audioInCount() > 0)
- {
-#ifdef BUILD_BRIDGE
- osc_send_bridge_set_inpeak(1);
- osc_send_bridge_set_inpeak(2);
-#else
- osc_send_control_set_input_peak_value(id, 1);
- osc_send_control_set_input_peak_value(id, 2);
-#endif
- }
- if (plugin->audioOutCount() > 0)
- {
-#ifdef BUILD_BRIDGE
- osc_send_bridge_set_outpeak(1);
- osc_send_bridge_set_outpeak(2);
-#else
- osc_send_control_set_output_peak_value(id, 1);
- osc_send_control_set_output_peak_value(id, 2);
-#endif
- }
-}
-
-#ifndef BUILD_BRIDGE
-void CarlaEngine::osc_send_control_add_plugin_start(const int32_t pluginId, const char* const pluginName)
-{
- qDebug("CarlaEngine::osc_send_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(pluginName);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+18];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/add_plugin_start");
- lo_send(m_oscData->target, target_path, "is", pluginId, pluginName);
- }
-}
-
-void CarlaEngine::osc_send_control_add_plugin_end(const int32_t pluginId)
-{
- qDebug("CarlaEngine::osc_send_control_add_plugin_end(%i)", pluginId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+16];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/add_plugin_end");
- lo_send(m_oscData->target, target_path, "i", pluginId);
- }
-}
-
-void CarlaEngine::osc_send_control_remove_plugin(const int32_t pluginId)
-{
- qDebug("CarlaEngine::osc_send_control_remove_plugin(%i)", pluginId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+15];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/remove_plugin");
- lo_send(m_oscData->target, target_path, "i", pluginId);
- }
-}
-
-void CarlaEngine::osc_send_control_set_plugin_data(const int32_t pluginId, const int32_t type, const int32_t category, const int32_t hints, const char* const realName, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId)
-{
- qDebug("CarlaEngine::osc_send_control_set_plugin_data(%i, %i, %i, %i, \"%s\", \"%s\", \"%s\", \"%s\", " P_INT64 ")", pluginId, type, category, hints, realName, label, maker, copyright, uniqueId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(type != PLUGIN_NONE);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+17];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_plugin_data");
- lo_send(m_oscData->target, target_path, "iiiissssh", pluginId, type, category, hints, realName, label, maker, copyright, uniqueId);
- }
-}
-
-void CarlaEngine::osc_send_control_set_plugin_ports(const int32_t pluginId, const int32_t audioIns, const int32_t audioOuts, const int32_t midiIns, const int32_t midiOuts, const int32_t cIns, const int32_t cOuts, const int32_t cTotals)
-{
- qDebug("CarlaEngine::osc_send_control_set_plugin_ports(%i, %i, %i, %i, %i, %i, %i, %i)", pluginId, audioIns, audioOuts, midiIns, midiOuts, cIns, cOuts, cTotals);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+18];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_plugin_ports");
- lo_send(m_oscData->target, target_path, "iiiiiiii", pluginId, audioIns, audioOuts, midiIns, midiOuts, cIns, cOuts, cTotals);
- }
-}
-
-void CarlaEngine::osc_send_control_set_parameter_data(const int32_t pluginId, const int32_t index, const int32_t type, const int32_t hints, const char* const name, const char* const label, const double current)
-{
- qDebug("CarlaEngine::osc_send_control_set_parameter_data(%i, %i, %i, %i, \"%s\", \"%s\", %g)", pluginId, index, type, hints, name, label, current);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
- CARLA_ASSERT(type != PARAMETER_UNKNOWN);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+20];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_parameter_data");
- lo_send(m_oscData->target, target_path, "iiiissd", pluginId, index, type, hints, name, label, current);
- }
-}
-
-void CarlaEngine::osc_send_control_set_parameter_ranges(const int32_t pluginId, const int32_t index, const double min, const double max, const double def, const double step, const double stepSmall, const double stepLarge)
-{
- qDebug("CarlaEngine::osc_send_control_set_parameter_ranges(%i, %i, %g, %g, %g, %g, %g, %g)", pluginId, index, min, max, def, step, stepSmall, stepLarge);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
- CARLA_ASSERT(min < max);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+22];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_parameter_ranges");
- lo_send(m_oscData->target, target_path, "iidddddd", pluginId, index, min, max, def, step, stepSmall, stepLarge);
- }
-}
-
-void CarlaEngine::osc_send_control_set_parameter_midi_cc(const int32_t pluginId, const int32_t index, const int32_t cc)
-{
- qDebug("CarlaEngine::osc_send_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_parameter_midi_cc");
- lo_send(m_oscData->target, target_path, "iii", pluginId, index, cc);
- }
-}
-
-void CarlaEngine::osc_send_control_set_parameter_midi_channel(const int32_t pluginId, const int32_t index, const int32_t channel)
-{
- qDebug("CarlaEngine::osc_send_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
- CARLA_ASSERT(channel >= 0 && channel < 16);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+28];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_parameter_midi_channel");
- lo_send(m_oscData->target, target_path, "iii", pluginId, index, channel);
- }
-}
-
-void CarlaEngine::osc_send_control_set_parameter_value(const int32_t pluginId, const int32_t index, const double value)
-{
-#if DEBUG
- if (index < 0)
- qDebug("CarlaEngine::osc_send_control_set_parameter_value(%i, %s, %g)", pluginId, InternalParametersIndex2Str((InternalParametersIndex)index), value);
- else
- qDebug("CarlaEngine::osc_send_control_set_parameter_value(%i, %i, %g)", pluginId, index, value);
-#endif
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+21];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_parameter_value");
- lo_send(m_oscData->target, target_path, "iid", pluginId, index, value);
- }
-}
-
-void CarlaEngine::osc_send_control_set_default_value(const int32_t pluginId, const int32_t index, const double value)
-{
- qDebug("CarlaEngine::osc_send_control_set_default_value(%i, %i, %g)", pluginId, index, value);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+19];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_default_value");
- lo_send(m_oscData->target, target_path, "iid", pluginId, index, value);
- }
-}
-
-void CarlaEngine::osc_send_control_set_program(const int32_t pluginId, const int32_t index)
-{
- qDebug("CarlaEngine::osc_send_control_set_program(%i, %i)", pluginId, index);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+13];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_program");
- lo_send(m_oscData->target, target_path, "ii", pluginId, index);
- }
-}
-
-void CarlaEngine::osc_send_control_set_program_count(const int32_t pluginId, const int32_t count)
-{
- qDebug("CarlaEngine::osc_send_control_set_program_count(%i, %i)", pluginId, count);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(count >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+19];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_program_count");
- lo_send(m_oscData->target, target_path, "ii", pluginId, count);
- }
-}
-
-void CarlaEngine::osc_send_control_set_program_name(const int32_t pluginId, const int32_t index, const char* const name)
-{
- qDebug("CarlaEngine::osc_send_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
- CARLA_ASSERT(name);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+18];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_program_name");
- lo_send(m_oscData->target, target_path, "iis", pluginId, index, name);
- }
-}
-
-void CarlaEngine::osc_send_control_set_midi_program(const int32_t pluginId, const int32_t index)
-{
- qDebug("CarlaEngine::osc_send_control_set_midi_program(%i, %i)", pluginId, index);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+18];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_midi_program");
- lo_send(m_oscData->target, target_path, "ii", pluginId, index);
- }
-}
-
-void CarlaEngine::osc_send_control_set_midi_program_count(const int32_t pluginId, const int32_t count)
-{
- qDebug("CarlaEngine::osc_send_control_set_midi_program_count(%i, %i)", pluginId, count);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(count >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+24];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_midi_program_count");
- lo_send(m_oscData->target, target_path, "ii", pluginId, count);
- }
-}
-
-void CarlaEngine::osc_send_control_set_midi_program_data(const int32_t pluginId, const int32_t index, const int32_t bank, const int32_t program, const char* const name)
-{
- qDebug("CarlaEngine::osc_send_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(index >= 0);
- CARLA_ASSERT(bank >= 0);
- CARLA_ASSERT(program >= 0);
- CARLA_ASSERT(name);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_midi_program_data");
- lo_send(m_oscData->target, target_path, "iiiis", pluginId, index, bank, program, name);
- }
-}
-
-void CarlaEngine::osc_send_control_note_on(const int32_t pluginId, const int32_t channel, const int32_t note, const int32_t velo)
-{
- qDebug("CarlaEngine::osc_send_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(channel >= 0 && channel < 16);
- CARLA_ASSERT(note >= 0 && note < 128);
- CARLA_ASSERT(velo > 0 && velo < 128);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+9];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/note_on");
- lo_send(m_oscData->target, target_path, "iiii", pluginId, channel, note, velo);
- }
-}
-
-void CarlaEngine::osc_send_control_note_off(const int32_t pluginId, const int32_t channel, const int32_t note)
-{
- qDebug("CarlaEngine::osc_send_control_note_off(%i, %i, %i)", pluginId, channel, note);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(channel >= 0 && channel < 16);
- CARLA_ASSERT(note >= 0 && note < 128);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+10];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/note_off");
- lo_send(m_oscData->target, target_path, "iii", pluginId, channel, note);
- }
-}
-
-void CarlaEngine::osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId)
-{
- //qDebug("CarlaEngine::osc_send_control_set_input_peak_value(%i, %i)", pluginId, portId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(portId == 1 || portId == 2);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+22];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_input_peak_value");
- lo_send(m_oscData->target, target_path, "iid", pluginId, portId, m_insPeak[pluginId*MAX_PEAKS + portId-1]);
- }
-}
-
-void CarlaEngine::osc_send_control_set_output_peak_value(const int32_t pluginId, const int32_t portId)
-{
- //qDebug("CarlaEngine::osc_send_control_set_output_peak_value(%i, %i)", pluginId, portId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(pluginId >= 0 && pluginId < m_maxPluginNumber);
- CARLA_ASSERT(portId == 1 || portId == 2);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/set_output_peak_value");
- lo_send(m_oscData->target, target_path, "iid", pluginId, portId, m_outsPeak[pluginId*MAX_PEAKS + portId-1]);
- }
-}
-
-void CarlaEngine::osc_send_control_exit()
-{
- qDebug("CarlaEngine::osc_send_control_exit()");
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+6];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/exit");
- lo_send(m_oscData->target, target_path, "");
- }
-}
-#else
-void CarlaEngine::osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total)
-{
- qDebug("CarlaEngine::osc_send_bridge_audio_count(%i, %i, %i)", ins, outs, total);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(total >= 0 && total >= ins + outs);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+20];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_audio_count");
- lo_send(m_oscData->target, target_path, "iii", ins, outs, total);
- }
-}
-
-void CarlaEngine::osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total)
-{
- qDebug("CarlaEngine::osc_send_bridge_midi_count(%i, %i, %i)", ins, outs, total);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(total >= 0 && total >= ins + outs);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+19];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_midi_count");
- lo_send(m_oscData->target, target_path, "iii", ins, outs, total);
- }
-}
-
-void CarlaEngine::osc_send_bridge_parameter_count(const int32_t ins, const int32_t outs, const int32_t total)
-{
- qDebug("CarlaEngine::osc_send_bridge_parameter_count(%i, %i, %i)", ins, outs, total);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(total >= 0 && total >= ins + outs);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+24];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_parameter_count");
- lo_send(m_oscData->target, target_path, "iii", ins, outs, total);
- }
-}
-
-void CarlaEngine::osc_send_bridge_program_count(const int32_t count)
-{
- qDebug("CarlaEngine::osc_send_bridge_program_count(%i)", count);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(count >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+22];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_program_count");
- lo_send(m_oscData->target, target_path, "i", count);
- }
-}
-
-void CarlaEngine::osc_send_bridge_midi_program_count(const int32_t count)
-{
- qDebug("CarlaEngine::osc_send_bridge_midi_program_count(%i)", count);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(count >= 0);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+27];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_midi_program_count");
- lo_send(m_oscData->target, target_path, "i", count);
- }
-}
-
-void CarlaEngine::osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId)
-{
- qDebug("CarlaEngine::osc_send_bridge_plugin_info(%i, %i, \"%s\", \"%s\", \"%s\", \"%s\", " P_INT64 ")", category, hints, name, label, maker, copyright, uniqueId);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(name);
- CARLA_ASSERT(label);
- CARLA_ASSERT(maker);
- CARLA_ASSERT(copyright);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+20];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_plugin_info");
- lo_send(m_oscData->target, target_path, "iissssh", category, hints, name, label, maker, copyright, uniqueId);
- }
-}
-
-void CarlaEngine::osc_send_bridge_parameter_info(const int32_t index, const char* const name, const char* const unit)
-{
- qDebug("CarlaEngine::osc_send_bridge_parameter_info(%i, \"%s\", \"%s\")", index, name, unit);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(name);
- CARLA_ASSERT(unit);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_parameter_info");
- lo_send(m_oscData->target, target_path, "iss", index, name, unit);
- }
-}
-
-void CarlaEngine::osc_send_bridge_parameter_data(const int32_t index, const int32_t type, const int32_t rindex, const int32_t hints, const int32_t midiChannel, const int32_t midiCC)
-{
- qDebug("CarlaEngine::osc_send_bridge_parameter_data(%i, %i, %i, %i, %i, %i)", index, type, rindex, hints, midiChannel, midiCC);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_parameter_data");
- lo_send(m_oscData->target, target_path, "iiiiii", index, type, rindex, hints, midiChannel, midiCC);
- }
-}
-
-void CarlaEngine::osc_send_bridge_parameter_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge)
-{
- qDebug("CarlaEngine::osc_send_bridge_parameter_ranges(%i, %g, %g, %g, %g, %g, %g)", index, def, min, max, step, stepSmall, stepLarge);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+25];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_parameter_ranges");
- lo_send(m_oscData->target, target_path, "idddddd", index, def, min, max, step, stepSmall, stepLarge);
- }
-}
-
-void CarlaEngine::osc_send_bridge_program_info(const int32_t index, const char* const name)
-{
- qDebug("CarlaEngine::osc_send_bridge_program_info(%i, \"%s\")", index, name);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+21];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_program_info");
- lo_send(m_oscData->target, target_path, "is", index, name);
- }
-}
-
-void CarlaEngine::osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label)
-{
- qDebug("CarlaEngine::osc_send_bridge_midi_program_info(%i, %i, %i, \"%s\")", index, bank, program, label);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+26];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_midi_program_info");
- lo_send(m_oscData->target, target_path, "iiis", index, bank, program, label);
- }
-}
-
-void CarlaEngine::osc_send_bridge_configure(const char* const key, const char* const value)
-{
- qDebug("CarlaEngine::osc_send_bridge_configure(\"%s\", \"%s\")", key, value);
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(key);
- CARLA_ASSERT(value);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+18];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_configure");
- lo_send(m_oscData->target, target_path, "ss", key, value);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_parameter_value(const int32_t index, const double value)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_parameter_value(%i, %g)", index, value);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+28];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_parameter_value");
- lo_send(m_oscData->target, target_path, "id", index, value);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_default_value(const int32_t index, const double value)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_default_value(%i, %g)", index, value);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+26];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_default_value");
- lo_send(m_oscData->target, target_path, "id", index, value);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_program(const int32_t index)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_program(%i)", index);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+20];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_program");
- lo_send(m_oscData->target, target_path, "i", index);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_midi_program(const int32_t index)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_midi_program(%i)", index);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+25];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_midi_program");
- lo_send(m_oscData->target, target_path, "i", index);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_custom_data(const char* const type, const char* const key, const char* const value)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+24];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_custom_data");
- lo_send(m_oscData->target, target_path, "sss", type, key, value);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_chunk_data(const char* const chunkFile)
-{
- qDebug("CarlaEngine::osc_send_bridge_set_chunk_data(\"%s\")", chunkFile);
- CARLA_ASSERT(m_oscData);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+23];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_chunk_data");
- lo_send(m_oscData->target, target_path, "s", chunkFile);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_inpeak(const int32_t portId)
-{
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(portId == 1 || portId == 2);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+28];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_inpeak");
- lo_send(m_oscData->target, target_path, "id", portId, m_insPeak[portId-1]);
- }
-}
-
-void CarlaEngine::osc_send_bridge_set_outpeak(const int32_t portId)
-{
- CARLA_ASSERT(m_oscData);
- CARLA_ASSERT(portId == 1 || portId == 2);
-
- if (m_oscData && m_oscData->target)
- {
- char target_path[strlen(m_oscData->path)+29];
- strcpy(target_path, m_oscData->path);
- strcat(target_path, "/bridge_set_outpeak");
- lo_send(m_oscData->target, target_path, "id", portId, m_insPeak[portId-1]);
- }
-}
-#endif
-
-CARLA_BACKEND_END_NAMESPACE
diff --git a/c++/carla-engine/carla_engine.doxygen b/c++/carla-engine/carla_engine.doxygen
deleted file mode 100644
index 533a401..0000000
--- a/c++/carla-engine/carla_engine.doxygen
+++ /dev/null
@@ -1,287 +0,0 @@
-# Doxyfile 1.7.6.1
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-DOXYFILE_ENCODING = UTF-8
-PROJECT_NAME = "Carla Engine"
-PROJECT_NUMBER =
-PROJECT_BRIEF =
-PROJECT_LOGO =
-OUTPUT_DIRECTORY = ../../doc/carla-engine
-CREATE_SUBDIRS = NO
-OUTPUT_LANGUAGE = English
-BRIEF_MEMBER_DESC = YES
-REPEAT_BRIEF = YES
-ABBREVIATE_BRIEF =
-ALWAYS_DETAILED_SEC = NO
-INLINE_INHERITED_MEMB = NO
-FULL_PATH_NAMES = YES
-STRIP_FROM_PATH =
-STRIP_FROM_INC_PATH =
-SHORT_NAMES = NO
-JAVADOC_AUTOBRIEF = NO
-QT_AUTOBRIEF = NO
-MULTILINE_CPP_IS_BRIEF = NO
-INHERIT_DOCS = YES
-SEPARATE_MEMBER_PAGES = NO
-TAB_SIZE = 4
-ALIASES =
-TCL_SUBST =
-OPTIMIZE_OUTPUT_FOR_C = NO
-OPTIMIZE_OUTPUT_JAVA = NO
-OPTIMIZE_FOR_FORTRAN = NO
-OPTIMIZE_OUTPUT_VHDL = NO
-EXTENSION_MAPPING =
-BUILTIN_STL_SUPPORT = NO
-CPP_CLI_SUPPORT = NO
-SIP_SUPPORT = NO
-IDL_PROPERTY_SUPPORT = YES
-DISTRIBUTE_GROUP_DOC = NO
-SUBGROUPING = YES
-INLINE_GROUPED_CLASSES = NO
-INLINE_SIMPLE_STRUCTS = NO
-TYPEDEF_HIDES_STRUCT = NO
-SYMBOL_CACHE_SIZE = 0
-LOOKUP_CACHE_SIZE = 0
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-EXTRACT_ALL = YES
-EXTRACT_PRIVATE = NO
-EXTRACT_STATIC = NO
-EXTRACT_LOCAL_CLASSES = YES
-EXTRACT_LOCAL_METHODS = NO
-EXTRACT_ANON_NSPACES = NO
-HIDE_UNDOC_MEMBERS = NO
-HIDE_UNDOC_CLASSES = NO
-HIDE_FRIEND_COMPOUNDS = NO
-HIDE_IN_BODY_DOCS = NO
-INTERNAL_DOCS = NO
-CASE_SENSE_NAMES = YES
-HIDE_SCOPE_NAMES = NO
-SHOW_INCLUDE_FILES = YES
-FORCE_LOCAL_INCLUDES = NO
-INLINE_INFO = YES
-SORT_MEMBER_DOCS = NO
-SORT_BRIEF_DOCS = NO
-SORT_MEMBERS_CTORS_1ST = NO
-SORT_GROUP_NAMES = NO
-SORT_BY_SCOPE_NAME = NO
-STRICT_PROTO_MATCHING = NO
-GENERATE_TODOLIST = YES
-GENERATE_TESTLIST = YES
-GENERATE_BUGLIST = YES
-GENERATE_DEPRECATEDLIST= YES
-ENABLED_SECTIONS =
-MAX_INITIALIZER_LINES = 30
-SHOW_USED_FILES = YES
-SHOW_DIRECTORIES = NO
-SHOW_FILES = YES
-SHOW_NAMESPACES = YES
-FILE_VERSION_FILTER =
-LAYOUT_FILE =
-CITE_BIB_FILES =
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-QUIET = NO
-WARNINGS = YES
-WARN_IF_UNDOCUMENTED = YES
-WARN_IF_DOC_ERROR = YES
-WARN_NO_PARAMDOC = NO
-WARN_FORMAT = "$file:$line: $text"
-WARN_LOGFILE =
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-INPUT =
-INPUT_ENCODING = UTF-8
-FILE_PATTERNS =
-RECURSIVE = NO
-EXCLUDE = carla_engine.cpp carla_engine_osc.hpp carla_engine_osc.cpp carla_engine_thread.hpp carla_engine_thread.cpp DistrhoPluginInfo.h
-EXCLUDE_SYMLINKS = NO
-EXCLUDE_PATTERNS =
-EXCLUDE_SYMBOLS =
-EXAMPLE_PATH =
-EXAMPLE_PATTERNS =
-EXAMPLE_RECURSIVE = NO
-IMAGE_PATH =
-INPUT_FILTER =
-FILTER_PATTERNS =
-FILTER_SOURCE_FILES = NO
-FILTER_SOURCE_PATTERNS =
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-SOURCE_BROWSER = NO
-INLINE_SOURCES = NO
-STRIP_CODE_COMMENTS = YES
-REFERENCED_BY_RELATION = NO
-REFERENCES_RELATION = NO
-REFERENCES_LINK_SOURCE = YES
-USE_HTAGS = NO
-VERBATIM_HEADERS = YES
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-ALPHABETICAL_INDEX = YES
-COLS_IN_ALPHA_INDEX = 5
-IGNORE_PREFIX =
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-GENERATE_HTML = YES
-HTML_OUTPUT = .
-HTML_FILE_EXTENSION = .html
-HTML_HEADER =
-HTML_FOOTER =
-HTML_STYLESHEET =
-HTML_EXTRA_FILES =
-HTML_COLORSTYLE_HUE = 220
-HTML_COLORSTYLE_SAT = 100
-HTML_COLORSTYLE_GAMMA = 80
-HTML_TIMESTAMP = YES
-HTML_ALIGN_MEMBERS = YES
-HTML_DYNAMIC_SECTIONS = NO
-GENERATE_DOCSET = NO
-DOCSET_FEEDNAME = "Doxygen generated docs"
-DOCSET_BUNDLE_ID = org.doxygen.Project
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-DOCSET_PUBLISHER_NAME = Publisher
-GENERATE_HTMLHELP = NO
-CHM_FILE =
-HHC_LOCATION =
-GENERATE_CHI = NO
-CHM_INDEX_ENCODING =
-BINARY_TOC = NO
-TOC_EXPAND = NO
-GENERATE_QHP = NO
-QCH_FILE =
-QHP_NAMESPACE = org.doxygen.Project
-QHP_VIRTUAL_FOLDER = doc
-QHP_CUST_FILTER_NAME =
-QHP_CUST_FILTER_ATTRS =
-QHP_SECT_FILTER_ATTRS =
-QHG_LOCATION =
-GENERATE_ECLIPSEHELP = NO
-ECLIPSE_DOC_ID = org.doxygen.Project
-DISABLE_INDEX = NO
-GENERATE_TREEVIEW = NO
-ENUM_VALUES_PER_LINE = 4
-USE_INLINE_TREES = NO
-TREEVIEW_WIDTH = 250
-EXT_LINKS_IN_WINDOW = NO
-FORMULA_FONTSIZE = 10
-FORMULA_TRANSPARENT = YES
-USE_MATHJAX = NO
-MATHJAX_RELPATH = http://www.mathjax.org/mathjax
-MATHJAX_EXTENSIONS =
-SEARCHENGINE = YES
-SERVER_BASED_SEARCH = NO
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-GENERATE_LATEX = NO
-LATEX_OUTPUT = latex
-LATEX_CMD_NAME = latex
-MAKEINDEX_CMD_NAME = makeindex
-COMPACT_LATEX = NO
-PAPER_TYPE = a4
-EXTRA_PACKAGES =
-LATEX_HEADER =
-LATEX_FOOTER =
-PDF_HYPERLINKS = YES
-USE_PDFLATEX = YES
-LATEX_BATCHMODE = NO
-LATEX_HIDE_INDICES = NO
-LATEX_SOURCE_CODE = NO
-LATEX_BIB_STYLE = plain
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-GENERATE_RTF = NO
-RTF_OUTPUT = rtf
-COMPACT_RTF = NO
-RTF_HYPERLINKS = NO
-RTF_STYLESHEET_FILE =
-RTF_EXTENSIONS_FILE =
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-GENERATE_MAN = NO
-MAN_OUTPUT = man
-MAN_EXTENSION = .3
-MAN_LINKS = NO
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-GENERATE_XML = NO
-XML_OUTPUT = xml
-XML_SCHEMA =
-XML_DTD =
-XML_PROGRAMLISTING = YES
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-GENERATE_AUTOGEN_DEF = NO
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-GENERATE_PERLMOD = NO
-PERLMOD_LATEX = NO
-PERLMOD_PRETTY = YES
-PERLMOD_MAKEVAR_PREFIX =
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-ENABLE_PREPROCESSING = YES
-MACRO_EXPANSION = NO
-EXPAND_ONLY_PREDEF = NO
-SEARCH_INCLUDES = YES
-INCLUDE_PATH =
-INCLUDE_FILE_PATTERNS =
-PREDEFINED = DOXYGEN CARLA_ENGINE_JACK CARLA_ENGINE_RTAUDIO CARLA_ENGINE_PLUGIN
-EXPAND_AS_DEFINED =
-SKIP_FUNCTION_MACROS = YES
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-TAGFILES =
-GENERATE_TAGFILE =
-ALLEXTERNALS = NO
-EXTERNAL_GROUPS = YES
-PERL_PATH = /usr/bin/perl
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-CLASS_DIAGRAMS = YES
-MSCGEN_PATH =
-HIDE_UNDOC_RELATIONS = YES
-HAVE_DOT = NO
-DOT_NUM_THREADS = 0
-DOT_FONTNAME = Helvetica
-DOT_FONTSIZE = 10
-DOT_FONTPATH =
-CLASS_GRAPH = YES
-COLLABORATION_GRAPH = YES
-GROUP_GRAPHS = YES
-UML_LOOK = NO
-TEMPLATE_RELATIONS = NO
-INCLUDE_GRAPH = YES
-INCLUDED_BY_GRAPH = YES
-CALL_GRAPH = NO
-CALLER_GRAPH = NO
-GRAPHICAL_HIERARCHY = YES
-DIRECTORY_GRAPH = YES
-DOT_IMAGE_FORMAT = png
-INTERACTIVE_SVG = NO
-DOT_PATH =
-DOTFILE_DIRS =
-MSCFILE_DIRS =
-DOT_GRAPH_MAX_NODES = 50
-MAX_DOT_GRAPH_DEPTH = 0
-DOT_TRANSPARENT = NO
-DOT_MULTI_TARGETS = YES
-GENERATE_LEGEND = YES
-DOT_CLEANUP = YES
diff --git a/c++/carla-engine/carla_engine.hpp b/c++/carla-engine/carla_engine.hpp
deleted file mode 100644
index 8e86c71..0000000
--- a/c++/carla-engine/carla_engine.hpp
+++ /dev/null
@@ -1,985 +0,0 @@
-/*
- * Carla Engine
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_ENGINE_HPP
-#define CARLA_ENGINE_HPP
-
-#include "carla_engine_osc.hpp"
-#include "carla_engine_thread.hpp"
-
-#include
-
-CARLA_BACKEND_START_NAMESPACE
-
-/*!
- * @defgroup CarlaBackendEngine Carla Backend Engine
- *
- * The Carla Backend Engine
- * @{
- */
-
-/*!
- * @defgroup TimeInfoValidHints TimeInfo Valid Hints
- *
- * Various hints used for CarlaTimeInfo::valid.
- * @{
- */
-const uint32_t CarlaEngineTimeBBT = 0x1;
-/**@}*/
-
-/*!
- * The type of an engine.
- */
-enum CarlaEngineType {
- /*!
- * Null engine type.
- */
- CarlaEngineTypeNull = 0,
-
- /*!
- * Jack engine type.\n
- * Provides single, multi-client, and rack processing modes.
- */
- CarlaEngineTypeJack = 1,
-
- /*!
- * RtAudio engine type, used to provide ALSA, PulseAudio, DirectSound, ASIO and CoreAudio/Midi support.\n
- * Provides rack mode processing only.
- */
- CarlaEngineTypeRtAudio = 2,
-
- /*!
- * Plugin engine type, used to export the engine as a plugin (DSSI, LV2 and VST) via the DISTRHO Plugin Toolkit.\n
- * Works in rack mode only.
- */
- CarlaEngineTypePlugin = 3
-};
-
-/*!
- * The type of an engine port.
- */
-enum CarlaEnginePortType {
- /*!
- * Null engine port type.
- */
- CarlaEnginePortTypeNull = 0,
-
- /*!
- * Audio port.
- */
- CarlaEnginePortTypeAudio = 1,
-
- /*!
- * Control port.\n
- * These are MIDI ports on some engine types, by handling MIDI-CC as control.
- */
- CarlaEnginePortTypeControl = 2,
-
- /*!
- * MIDI port.
- */
- CarlaEnginePortTypeMIDI = 3
-};
-
-/*!
- * The type of a control event.
- */
-enum CarlaEngineControlEventType {
- /*!
- * Null event type.
- */
- CarlaEngineNullEvent = 0,
-
- /*!
- * Parameter change event.\n
- * \note Value uses a range of 0.0<->1.0.
- */
- CarlaEngineParameterChangeEvent = 1,
-
- /*!
- * MIDI Bank change event.
- */
- CarlaEngineMidiBankChangeEvent = 2,
-
- /*!
- * MIDI Program change event.
- */
- CarlaEngineMidiProgramChangeEvent = 3,
-
- /*!
- * All sound off event.
- */
- CarlaEngineAllSoundOffEvent = 4,
-
- /*!
- * All notes off event.
- */
- CarlaEngineAllNotesOffEvent = 5
-};
-
-/*!
- * Engine control event.
- */
-struct CarlaEngineControlEvent {
- CarlaEngineControlEventType type;
- uint32_t time;
- uint8_t channel;
- uint16_t parameter;
- double value;
-
- CarlaEngineControlEvent()
- : type(CarlaEngineNullEvent),
- time(0),
- channel(0),
- parameter(0),
- value(0.0) {}
-};
-
-/*!
- * Engine MIDI event.
- */
-struct CarlaEngineMidiEvent {
- uint32_t time;
- uint8_t size;
- uint8_t data[3];
-
- CarlaEngineMidiEvent()
- : time(0),
- size(0),
- data{0} {}
-};
-
-/*!
- * Engine BBT Time information.
- */
-struct CarlaEngineTimeInfoBBT {
- int32_t bar;
- int32_t beat;
- int32_t tick;
- double bar_start_tick;
- float beats_per_bar;
- float beat_type;
- double ticks_per_beat;
- double beats_per_minute;
-
- CarlaEngineTimeInfoBBT()
- : bar(0),
- beat(0),
- tick(0),
- bar_start_tick(0.0),
- beats_per_bar(0.0f),
- beat_type(0.0f),
- ticks_per_beat(0.0),
- beats_per_minute(0.0) {}
-};
-
-/*!
- * Engine Time information.
- */
-struct CarlaEngineTimeInfo {
- bool playing;
- uint32_t frame;
- uint32_t time;
- uint32_t valid;
- CarlaEngineTimeInfoBBT bbt;
-
- CarlaEngineTimeInfo()
- : playing(false),
- frame(0),
- time(0),
- valid(0) {}
-};
-
-/*!
- * Engine options.
- */
-struct CarlaEngineOptions {
- ProcessMode processMode;
- bool processHighPrecision;
-
- uint maxParameters;
- uint preferredBufferSize;
- uint preferredSampleRate;
-
- bool forceStereo;
- bool useDssiVstChunks;
-
- bool preferPluginBridges;
- bool preferUiBridges;
- uint oscUiTimeout;
-
- CarlaString bridge_posix32;
- CarlaString bridge_posix64;
- CarlaString bridge_win32;
- CarlaString bridge_win64;
- CarlaString bridge_lv2gtk2;
- CarlaString bridge_lv2gtk3;
- CarlaString bridge_lv2qt4;
- CarlaString bridge_lv2qt5;
- CarlaString bridge_lv2cocoa;
- CarlaString bridge_lv2win;
- CarlaString bridge_lv2x11;
- CarlaString bridge_vstcocoa;
- CarlaString bridge_vsthwnd;
- CarlaString bridge_vstx11;
-
- CarlaEngineOptions()
- : processMode(PROCESS_MODE_CONTINUOUS_RACK),
- processHighPrecision(false),
- maxParameters(MAX_PARAMETERS),
- preferredBufferSize(512),
- preferredSampleRate(44100),
- forceStereo(false),
- useDssiVstChunks(false),
- preferPluginBridges(false),
- preferUiBridges(true),
- oscUiTimeout(4000/100) {}
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Engine port (Base).\n
- * This is the base class for all Carla engine ports.
- */
-class CarlaEngineBasePort
-{
-public:
- /*!
- * The contructor.\n
- * Param \a isInput defines wherever this is an input port or not (output otherwise).\n
- * Input/output state is constant for the lifetime of the port.
- */
- CarlaEngineBasePort(const bool isInput, const ProcessMode processMode);
-
- /*!
- * The decontructor.
- */
- virtual ~CarlaEngineBasePort();
-
- /*!
- * Get the type of the port, as provided by the respective subclasses.
- */
- virtual CarlaEnginePortType type() const = 0;
-
- /*!
- * Initialize the port's internal buffer for \a engine.
- */
- virtual void initBuffer(CarlaEngine* const engine) = 0;
-
-protected:
- const bool isInput;
- const ProcessMode processMode;
- void* buffer;
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Engine port (Audio).
- */
-class CarlaEngineAudioPort : public CarlaEngineBasePort
-{
-public:
- /*!
- * The contructor.\n
- * Param \a isInput defines wherever this is an input port or not (output otherwise).\n
- * Input/output state is constant for the lifetime of the port.
- */
- CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode);
-
- /*!
- * The decontructor.
- */
- virtual ~CarlaEngineAudioPort();
-
- /*!
- * Get the type of the port, in this case CarlaEnginePortTypeAudio.
- */
- CarlaEnginePortType type() const
- {
- return CarlaEnginePortTypeAudio;
- }
-
- /*!
- * Initialize the port's internal buffer for \a engine.
- */
- virtual void initBuffer(CarlaEngine* const engine);
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Engine port (Control).
- */
-class CarlaEngineControlPort : public CarlaEngineBasePort
-{
-public:
- /*!
- * The contructor.\n
- * Param \a isInput defines wherever this is an input port or not (output otherwise).\n
- * Input/output state is constant for the lifetime of the port.
- */
- CarlaEngineControlPort(const bool isInput, const ProcessMode processMode);
-
- /*!
- * The decontructor.
- */
- virtual ~CarlaEngineControlPort();
-
- /*!
- * Get the type of the port, in this case CarlaEnginePortTypeControl.
- */
- CarlaEnginePortType type() const
- {
- return CarlaEnginePortTypeControl;
- }
-
- /*!
- * Initialize the port's internal buffer for \a engine.
- */
- virtual void initBuffer(CarlaEngine* const engine);
-
- /*!
- * Get the number of control events present in the buffer.
- * \note You must only call this for input ports.
- */
- virtual uint32_t getEventCount();
-
- /*!
- * Get the control event at \a index.
- ** \note You must only call this for input ports.
- */
- virtual const CarlaEngineControlEvent* getEvent(const uint32_t index);
-
- /*!
- * Write a control event to the buffer.\n
- * Arguments are the same as in the CarlaEngineControlEvent struct.
- ** \note You must only call this for output ports.
- */
- virtual void writeEvent(const CarlaEngineControlEventType type, const uint32_t time, const uint8_t channel, const uint16_t parameter, const double value);
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Engine port (MIDI).
- */
-class CarlaEngineMidiPort : public CarlaEngineBasePort
-{
-public:
- /*!
- * The contructor.\n
- * Param \a isInput defines wherever this is an input port or not (output otherwise).\n
- * Input/output state is constant for the lifetime of the port.
- */
- CarlaEngineMidiPort(const bool isInput, const ProcessMode processMode);
-
- /*!
- * The decontructor.
- */
- virtual ~CarlaEngineMidiPort();
-
- /*!
- * Get the type of the port, in this case CarlaEnginePortTypeMIDI.
- */
- CarlaEnginePortType type() const
- {
- return CarlaEnginePortTypeMIDI;
- }
-
- /*!
- * Initialize the port's internal buffer for \a engine.
- */
- virtual void initBuffer(CarlaEngine* const engine);
-
- /*!
- * Get the number of MIDI events present in the buffer.
- * \note You must only call this for input ports.
- */
- virtual uint32_t getEventCount();
-
- /*!
- * Get the MIDI event at \a index.
- ** \note You must only call this for input ports.
- */
- virtual const CarlaEngineMidiEvent* getEvent(const uint32_t index);
-
- /*!
- * Write a MIDI event to the buffer.\n
- * Arguments are the same as in the CarlaEngineMidiEvent struct.
- ** \note You must only call this for output ports.
- */
- virtual void writeEvent(const uint32_t time, const uint8_t* const data, const uint8_t size);
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Engine client.\n
- * Each plugin requires one client from the engine (created via CarlaEngine::addPort()).\n
- * \note This is a virtual class, each engine type provides its own funtionality.
- */
-class CarlaEngineClient
-{
-public:
- /*!
- * The contructor.\n
- * All constructor parameters are constant and will never change in the lifetime of the client.\n
- * Client starts in deactivated state.
- */
- CarlaEngineClient(const CarlaEngineType engineType, const ProcessMode processMode);
-
- /*!
- * The decontructor.
- */
- virtual ~CarlaEngineClient();
-
- /*!
- * Activate this client.\n
- * \note Client must be deactivated before calling this function.
- */
- virtual void activate();
-
- /*!
- * Deactivate this client.\n
- * \note Client must be activated before calling this function.
- */
- virtual void deactivate();
-
- /*!
- * Check if the client is activated.
- */
- virtual bool isActive() const;
-
- /*!
- * Check if the client is ok.\n
- * Plugins will refuse to instantiate if this returns false.
- * \note This is always true in rack and patchbay processing modes.
- */
- virtual bool isOk() const;
-
- /*!
- * Get the current latency, in samples.
- */
- virtual uint32_t getLatency() const;
-
- /*!
- * Change the client's latency.
- */
- virtual void setLatency(const uint32_t samples);
-
- /*!
- * Add a new port of type \a portType.
- * \note This function does nothing in rack processing mode since its ports are static (2 audio, 1 midi and 1 control for both input and output).
- */
- virtual const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput) = 0;
-
-protected:
- const CarlaEngineType engineType;
- const ProcessMode processMode;
-
-private:
- bool m_active;
- uint32_t m_latency;
-};
-
-// -----------------------------------------------------------------------
-
-/*!
- * Carla Engine.
- * \note This is a virtual class for all available engine types available in Carla.
- */
-class CarlaEngine
-{
-public:
- /*!
- * The decontructor.
- * The engine must have been closed before this happens.
- */
- virtual ~CarlaEngine();
-
- // -------------------------------------------------------------------
- // Static values and calls
-
- /*!
- * Maximum number of peaks per plugin.\n
- * \note There are both input and output peaks.
- */
- static const unsigned short MAX_PEAKS = 2;
-
- /*!
- * Get the number of available engine drivers.
- */
- static unsigned int getDriverCount();
-
- /*!
- * Get the name of the engine driver at \a index.
- */
- static const char* getDriverName(unsigned int index);
-
- /*!
- * Create a new engine, using driver \a driverName.\n
- * Returned variable must be deleted when no longer needed.
- */
- static CarlaEngine* newDriverByName(const char* const driverName);
-
- // -------------------------------------------------------------------
- // Maximum values
-
- /*!
- * Maximum client name size.
- */
- virtual int maxClientNameSize();
-
- /*!
- * Maximum port name size.
- */
- virtual int maxPortNameSize();
-
- /*!
- * Maximum number of loadable plugins.
- * \note This function returns 0 if engine is not started.
- */
- unsigned short maxPluginNumber() const;
-
- // -------------------------------------------------------------------
- // Virtual, per-engine type calls
-
- /*!
- * Initialize engine, using \a clientName.
- */
- virtual bool init(const char* const clientName);
-
- /*!
- * Close engine.
- */
- virtual bool close();
-
- /*!
- * Check if engine is running.
- */
- virtual bool isRunning() const = 0;
-
- /*!
- * Check if engine is running offline (aka freewheel mode).
- */
- virtual bool isOffline() const = 0;
-
- /*!
- * Get engine type.
- */
- virtual CarlaEngineType type() const = 0;
-
- /*!
- * Add new engine client.
- * \note This must only be called within a plugin class.
- */
- virtual CarlaEngineClient* addClient(CarlaPlugin* const plugin) = 0;
-
- // -------------------------------------------------------------------
- // Plugin management
-
- /*!
- * Get next available plugin id.\n
- * Returns -1 if no more plugins can be loaded.
- */
- short getNewPluginId() const;
-
- /*!
- * Get plugin with id \a id.
- */
- CarlaPlugin* getPlugin(const unsigned short id) const;
-
- /*!
- * Get plugin with id \a id, faster unchecked version.
- */
- CarlaPlugin* getPluginUnchecked(const unsigned short id) const;
-
- /*!
- * Get a unique plugin name within the engine.\n
- * Returned variable must be free'd when no longer needed.
- */
- const char* getUniquePluginName(const char* const name);
-
- /*!
- * Add new plugin.\n
- * Returns the id of the plugin, or -1 if the operation failed.
- */
- short addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr);
-
- /*!
- * Add new plugin, using native binary type.\n
- * Returns the id of the plugin, or -1 if the operation failed.
- */
- short addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, void* const extra = nullptr);
-
- /*!
- * Remove plugin with id \a id.
- */
- bool removePlugin(const unsigned short id);
-
- /*!
- * Remove all plugins.
- */
- void removeAllPlugins();
-
- /*!
- * Idle all plugins GUIs.
- */
- void idlePluginGuis();
-
- // bridge, internal use only
- // TODO - find a better way for this
- void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin)
- {
- m_carlaPlugins[id] = plugin;
- }
-
- // -------------------------------------------------------------------
- // Information (base)
-
- /*!
- * Get engine name.
- */
- const char* getName() const;
-
- /*!
- * Get current sample rate.
- */
- double getSampleRate() const;
-
- /*!
- * Get current buffer size.
- */
- uint32_t getBufferSize() const;
-
- /*!
- * Get current Time information.
- */
- const CarlaEngineTimeInfo* getTimeInfo() const;
-
- /*!
- * Tell the engine it's about to close.\n
- * This is used to prevent the engine thread from reactivating.
- */
- void aboutToClose();
-
- // -------------------------------------------------------------------
- // Information (audio peaks)
-
- double getInputPeak(const unsigned short pluginId, const unsigned short id) const;
- double getOutputPeak(const unsigned short pluginId, const unsigned short id) const;
- void setInputPeak(const unsigned short pluginId, const unsigned short id, double value);
- void setOutputPeak(const unsigned short pluginId, const unsigned short id, double value);
-
- // -------------------------------------------------------------------
- // Callback
-
- void callback(const CallbackType action, const unsigned short pluginId, const int value1, const int value2, const double value3, const char* const valueStr);
- void setCallback(const CallbackFunc func, void* const ptr);
-
- // -------------------------------------------------------------------
- // Error handling
-
- /*!
- * Get last error.
- */
- const char* getLastError() const;
-
- /*!
- * Set last error.
- */
- void setLastError(const char* const error);
-
- // -------------------------------------------------------------------
- // Options
-
- /*!
- * Get the engine options (read-only).
- */
- const CarlaEngineOptions& getOptions() const
- {
- return options;
- }
-
-#ifndef BUILD_BRIDGE
- /*!
- * Get the engine options as process environment.
- */
- const QProcessEnvironment& getOptionsAsProcessEnvironment() const
- {
- return m_procEnv;
- }
-
- /*!
- * Set the engine option \a option.
- */
- void setOption(const OptionsType option, const int value, const char* const valueStr);
-#endif
-
- // -------------------------------------------------------------------
- // Mutex locks
-
- /*!
- * Lock processing.
- */
- void processLock();
-
- /*!
- * Try Lock processing.
- */
- void processTryLock();
-
- /*!
- * Unlock processing.
- */
- void processUnlock();
-
- /*!
- * Lock MIDI.
- */
- void midiLock();
-
- /*!
- * Try Lock MIDI.
- */
- void midiTryLock();
-
- /*!
- * Unlock MIDI.
- */
- void midiUnlock();
-
- // -------------------------------------------------------------------
- // OSC Stuff
-
-#ifndef BUILD_BRIDGE
- /*!
- * Check if OSC controller is registered.
- */
- bool isOscControlRegistered() const;
-#else
- /*!
- * Check if OSC bridge is registered.
- */
- bool isOscBridgeRegistered() const;
-#endif
-
- /*!
- * Idle OSC.
- */
- void idleOsc();
-
- /*!
- * Get OSC TCP server path.
- */
- const char* getOscServerPathTCP() const;
-
- /*!
- * Get OSC UDP server path.
- */
- const char* getOscServerPathUDP() const;
-
-#ifdef BUILD_BRIDGE
- /*!
- * Set OSC bridge data.
- */
- void setOscBridgeData(const CarlaOscData* const oscData);
-#endif
-
-#ifdef BUILD_BRIDGE
- void osc_send_peaks(CarlaPlugin* const plugin);
-#else
- void osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id);
-#endif
-
-#ifdef BUILD_BRIDGE
- void osc_send_bridge_audio_count(const int32_t ins, const int32_t outs, const int32_t total);
- void osc_send_bridge_midi_count(const int32_t ins, const int32_t outs, const int32_t total);
- void osc_send_bridge_parameter_count(const int32_t ins, const int32_t outs, const int32_t total);
- void osc_send_bridge_program_count(const int32_t count);
- void osc_send_bridge_midi_program_count(const int32_t count);
- void osc_send_bridge_plugin_info(const int32_t category, const int32_t hints, const char* const name, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId);
- void osc_send_bridge_parameter_info(const int32_t index, const char* const name, const char* const unit);
- void osc_send_bridge_parameter_data(const int32_t index, const int32_t type, const int32_t rindex, const int32_t hints, const int32_t midiChannel, const int32_t midiCC);
- void osc_send_bridge_parameter_ranges(const int32_t index, const double def, const double min, const double max, const double step, const double stepSmall, const double stepLarge);
- void osc_send_bridge_program_info(const int32_t index, const char* const name);
- void osc_send_bridge_midi_program_info(const int32_t index, const int32_t bank, const int32_t program, const char* const label);
- void osc_send_bridge_configure(const char* const key, const char* const value);
- void osc_send_bridge_set_parameter_value(const int32_t index, const double value);
- void osc_send_bridge_set_default_value(const int32_t index, const double value);
- void osc_send_bridge_set_program(const int32_t index);
- void osc_send_bridge_set_midi_program(const int32_t index);
- void osc_send_bridge_set_custom_data(const char* const type, const char* const key, const char* const value);
- void osc_send_bridge_set_chunk_data(const char* const chunkFile);
- void osc_send_bridge_set_inpeak(const int32_t portId);
- void osc_send_bridge_set_outpeak(const int32_t portId);
-#else
- void osc_send_control_add_plugin_start(const int32_t pluginId, const char* const pluginName);
- void osc_send_control_add_plugin_end(const int32_t pluginId);
- void osc_send_control_remove_plugin(const int32_t pluginId);
- void osc_send_control_set_plugin_data(const int32_t pluginId, const int32_t type, const int32_t category, const int32_t hints, const char* const realName, const char* const label, const char* const maker, const char* const copyright, const int64_t uniqueId);
- void osc_send_control_set_plugin_ports(const int32_t pluginId, const int32_t audioIns, const int32_t audioOuts, const int32_t midiIns, const int32_t midiOuts, const int32_t cIns, const int32_t cOuts, const int32_t cTotals);
- void osc_send_control_set_parameter_data(const int32_t pluginId, const int32_t index, const int32_t type, const int32_t hints, const char* const name, const char* const label, const double current);
- void osc_send_control_set_parameter_ranges(const int32_t pluginId, const int32_t index, const double min, const double max, const double def, const double step, const double stepSmall, const double stepLarge);
- void osc_send_control_set_parameter_midi_cc(const int32_t pluginId, const int32_t index, const int32_t cc);
- void osc_send_control_set_parameter_midi_channel(const int32_t pluginId, const int32_t index, const int32_t channel);
- void osc_send_control_set_parameter_value(const int32_t pluginId, const int32_t index, const double value);
- void osc_send_control_set_default_value(const int32_t pluginId, const int32_t index, const double value);
- void osc_send_control_set_program(const int32_t pluginId, const int32_t index);
- void osc_send_control_set_program_count(const int32_t pluginId, const int32_t count);
- void osc_send_control_set_program_name(const int32_t pluginId, const int32_t index, const char* const name);
- void osc_send_control_set_midi_program(const int32_t pluginId, const int32_t index);
- void osc_send_control_set_midi_program_count(const int32_t pluginId, const int32_t count);
- void osc_send_control_set_midi_program_data(const int32_t pluginId, const int32_t index, const int32_t bank, const int32_t program, const char* const name);
- void osc_send_control_note_on(const int32_t pluginId, const int32_t channel, const int32_t note, const int32_t velo);
- void osc_send_control_note_off(const int32_t pluginId, const int32_t channel, const int32_t note);
- void osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId);
- void osc_send_control_set_output_peak_value(const int32_t pluginId, const int32_t portId);
- void osc_send_control_exit();
-#endif
-
-#ifndef BUILD_BRIDGE
- // -------------------------------------------------------------------
- // Rack mode
-
- static const unsigned short MAX_CONTROL_EVENTS = 512;
- static const unsigned short MAX_MIDI_EVENTS = 512;
- CarlaEngineControlEvent rackControlEventsIn[MAX_CONTROL_EVENTS];
- CarlaEngineControlEvent rackControlEventsOut[MAX_CONTROL_EVENTS];
- CarlaEngineMidiEvent rackMidiEventsIn[MAX_MIDI_EVENTS];
- CarlaEngineMidiEvent rackMidiEventsOut[MAX_MIDI_EVENTS];
-#endif
-
- // -------------------------------------
-
- /*!
- * \class ScopedLocker
- *
- * \brief Carla engine scoped locker
- *
- * This is a handy class that temporarily locks an engine during a function scope.
- */
- class ScopedLocker
- {
- public:
- /*!
- * Lock the engine \a engine if \a lock is true.
- * The engine is unlocked in the deconstructor of this class if \a lock is true.
- *
- * \param engine The engine to lock
- * \param lock Wherever to lock the engine or not, true by default
- */
- ScopedLocker(CarlaEngine* const engine, bool lock = true)
- : mutex(&engine->m_procLock),
- m_lock(lock)
- {
- if (m_lock)
- mutex->lock();
- }
-
- ~ScopedLocker()
- {
- if (m_lock)
- mutex->unlock();
- }
-
- private:
- QMutex* const mutex;
- const bool m_lock;
- };
-
- // -------------------------------------
-
-protected:
- /*!
- * The contructor, protected.\n
- * \note This only initializes engine data, it doesn't initialize the engine itself.
- */
- CarlaEngine();
-
-#ifndef BUILD_BRIDGE
- /*!
- * Proccess audio buffer in rack mode, protected.
- */
- void processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames);
-#endif
-
- CarlaEngineOptions options;
-
- CarlaString name;
- uint32_t bufferSize;
- double sampleRate;
- CarlaEngineTimeInfo timeInfo;
-
- void bufferSizeChanged(const uint32_t newBufferSize);
-
-private:
- CarlaEngineOsc m_osc;
- CarlaEngineThread m_thread;
-
- const CarlaOscData* m_oscData;
-
- CallbackFunc m_callback;
- void* m_callbackPtr;
- CarlaString m_lastError;
-
-#ifndef BUILD_BRIDGE
- QProcessEnvironment m_procEnv;
-#endif
-
- QMutex m_procLock;
- QMutex m_midiLock;
-
- CarlaPlugin* m_carlaPlugins[MAX_PLUGINS];
- const char* m_uniqueNames[MAX_PLUGINS];
-
- double m_insPeak[MAX_PLUGINS * MAX_PEAKS];
- double m_outsPeak[MAX_PLUGINS * MAX_PEAKS];
-
- bool m_aboutToClose;
- unsigned short m_maxPluginNumber;
-
-#ifdef CARLA_ENGINE_JACK
- static CarlaEngine* newJack();
-#endif
-#ifdef CARLA_ENGINE_RTAUDIO
- enum RtAudioApi {
- RTAUDIO_DUMMY = 0,
- RTAUDIO_LINUX_ALSA = 1,
- RTAUDIO_LINUX_PULSE = 2,
- RTAUDIO_LINUX_OSS = 3,
- RTAUDIO_UNIX_JACK = 4,
- RTAUDIO_MACOSX_CORE = 5,
- RTAUDIO_WINDOWS_ASIO = 6,
- RTAUDIO_WINDOWS_DS = 7
- };
-
- static CarlaEngine* newRtAudio(RtAudioApi api);
- static unsigned int getRtAudioApiCount();
- static const char* getRtAudioApiName(unsigned int index);
-#endif
-};
-
-// -----------------------------------------------------------------------
-
-/**@}*/
-
-CARLA_BACKEND_END_NAMESPACE
-
-#endif // CARLA_ENGINE_HPP
diff --git a/c++/carla-engine/carla_engine.pro b/c++/carla-engine/carla_engine.pro
deleted file mode 100644
index 2a71144..0000000
--- a/c++/carla-engine/carla_engine.pro
+++ /dev/null
@@ -1,71 +0,0 @@
-# QtCreator project file
-
-QT = core
-
-CONFIG = debug
-CONFIG += static
-CONFIG += link_pkgconfig qt warn_on
-
-DEFINES = DEBUG
-DEFINES += QTCREATOR_TEST
-
-# JACK
-DEFINES += CARLA_ENGINE_JACK
-
-# RtAudio/RtMidi
-DEFINES += CARLA_ENGINE_RTAUDIO HAVE_GETTIMEOFDAY _FORTIFY_SOURCE=2
-DEFINES += __LINUX_ALSA__ __LINUX_ALSASEQ__ __LINUX_PULSE__ __UNIX_JACK__
-DEFINES += __RTAUDIO_DEBUG__ __RTMIDI_DEBUG__
-
-# DISTRHO Plugin
-DEFINES += CARLA_ENGINE_PLUGIN
-DEFINES += DISTRHO_PLUGIN_TARGET_DSSI
-
-# Misc
-DEFINES += WANT_LV2
-
-PKGCONFIG = liblo jack alsa libpulse-simple
-
-TARGET = carla_engine
-TEMPLATE = lib
-VERSION = 0.5.0
-
-SOURCES = \
- carla_engine.cpp \
- carla_engine_osc.cpp \
- carla_engine_thread.cpp \
- jack.cpp \
- rtaudio.cpp \
- plugin.cpp
-
-HEADERS = \
- carla_engine.hpp \
- carla_engine_osc.hpp \
- carla_engine_thread.hpp
-
-HEADERS += \
- DistrhoPluginInfo.h
-
-INCLUDEPATH = . \
- ../carla-backend \
- ../carla-includes \
- ../carla-plugin \
- ../carla-utils
-
-# FIXME
-INCLUDEPATH += \
- /opt/kxstudio/include
-
-# JACK
-INCLUDEPATH += ../carla-jackbridge
-
-# RtAudio/RtMidi
-INCLUDEPATH += rtaudio-4.0.11
-INCLUDEPATH += rtmidi-2.0.1
-SOURCES += rtaudio-4.0.11/RtAudio.cpp
-SOURCES += rtmidi-2.0.1/RtMidi.cpp
-
-# Plugin
-INCLUDEPATH += ../distrho-plugin-toolkit
-
-QMAKE_CXXFLAGS *= -std=c++0x
diff --git a/c++/carla-engine/carla_engine_osc.cpp b/c++/carla-engine/carla_engine_osc.cpp
deleted file mode 100644
index 52beac5..0000000
--- a/c++/carla-engine/carla_engine_osc.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
- * Carla Engine OSC
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_engine.hpp"
-#include "carla_plugin.hpp"
-
-CARLA_BACKEND_START_NAMESPACE
-
-// -----------------------------------------------------------------------
-
-CarlaEngineOsc::CarlaEngineOsc(CarlaEngine* const engine_)
- : engine(engine_)
-{
- qDebug("CarlaEngineOsc::CarlaEngineOsc(%p)", engine);
- CARLA_ASSERT(engine);
-
- m_name = nullptr;
- m_nameSize = 0;
-
- m_serverTCP = nullptr;
- m_serverUDP = nullptr;
-}
-
-CarlaEngineOsc::~CarlaEngineOsc()
-{
- qDebug("CarlaEngineOsc::~CarlaEngineOsc()");
- CARLA_ASSERT(! m_name);
- CARLA_ASSERT(! m_serverTCP);
- CARLA_ASSERT(! m_serverUDP);
-}
-
-// -----------------------------------------------------------------------
-
-void CarlaEngineOsc::init(const char* const name)
-{
- qDebug("CarlaEngineOsc::init(\"%s\")", name);
- CARLA_ASSERT(! m_name);
- CARLA_ASSERT(! m_serverTCP);
- CARLA_ASSERT(! m_serverUDP);
- CARLA_ASSERT(m_nameSize == 0);
- CARLA_ASSERT(m_serverPathTCP.isEmpty());
- CARLA_ASSERT(m_serverPathUDP.isEmpty());
- CARLA_ASSERT(name);
-
- m_name = strdup(name ? name : "");
- m_nameSize = strlen(m_name);
-
- m_serverTCP = lo_server_new_with_proto(nullptr, LO_TCP, osc_error_handlerTCP);
- m_serverUDP = lo_server_new_with_proto(nullptr, LO_UDP, osc_error_handlerUDP);
-
- if (m_serverTCP)
- {
- if (char* const serverPathTCP = lo_server_get_url(m_serverTCP))
- {
- m_serverPathTCP = serverPathTCP;
- m_serverPathTCP += m_name;
- free(serverPathTCP);
- }
-
- lo_server_add_method(m_serverTCP, nullptr, nullptr, osc_message_handler, this);
- }
-
- if (m_serverUDP)
- {
- if (char* const serverPathUDP = lo_server_get_url(m_serverUDP))
- {
- m_serverPathUDP = serverPathUDP;
- m_serverPathUDP += m_name;
- free(serverPathUDP);
- }
-
- lo_server_add_method(m_serverUDP, nullptr, nullptr, osc_message_handler, this);
- }
-}
-
-void CarlaEngineOsc::idle()
-{
- if (m_serverTCP)
- {
- while (lo_server_recv_noblock(m_serverTCP, 0) != 0) {}
- }
-
- if (m_serverUDP)
- {
- while (lo_server_recv_noblock(m_serverUDP, 0) != 0) {}
- }
-}
-
-void CarlaEngineOsc::close()
-{
- qDebug("CarlaEngineOsc::close()");
- CARLA_ASSERT(m_name);
- CARLA_ASSERT(m_serverTCP);
- CARLA_ASSERT(m_serverUDP);
- CARLA_ASSERT(m_serverPathTCP.isNotEmpty());
- CARLA_ASSERT(m_serverPathUDP.isNotEmpty());
-
- m_nameSize = 0;
-
- if (m_name)
- {
- free(m_name);
- m_name = nullptr;
- }
-
- if (m_serverTCP)
- {
- lo_server_del_method(m_serverTCP, nullptr, nullptr);
- lo_server_free(m_serverTCP);
- m_serverTCP = nullptr;
- }
-
- if (m_serverUDP)
- {
- lo_server_del_method(m_serverUDP, nullptr, nullptr);
- lo_server_free(m_serverUDP);
- m_serverUDP = nullptr;
- }
-
- m_serverPathTCP.clear();
- m_serverPathUDP.clear();
-
-#ifndef BUILD_BRIDGE
- m_controlData.free();
-#endif
-}
-
-// -----------------------------------------------------------------------
-
-int CarlaEngineOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
-{
-#if DEBUG
- if (! QString(path).endsWith("peak"))
- qDebug("CarlaEngineOsc::handleMessage(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
-#endif
- CARLA_ASSERT(m_name);
- CARLA_ASSERT(m_serverTCP || m_serverUDP);
- CARLA_ASSERT(m_serverPathTCP.isNotEmpty() || m_serverPathUDP.isNotEmpty());
- CARLA_ASSERT(path);
-
- if (! path)
- {
- qCritical("CarlaEngineOsc::handleMessage() - got invalid path");
- return 1;
- }
-
- if (! m_name)
- {
- qCritical("CarlaEngineOsc::handleMessage(\"%s\", ...) - received message but client is offline", path);
- return 1;
- }
-
-#ifndef BUILD_BRIDGE
- // Initial path check
- if (strcmp(path, "/register") == 0)
- {
- const lo_address source = lo_message_get_source(msg);
- return handleMsgRegister(argc, argv, types, source);
- }
- if (strcmp(path, "/unregister") == 0)
- {
- return handleMsgUnregister();
- }
-#endif
-
- // Check if message is for this client
- if (strlen(path) <= m_nameSize || strncmp(path+1, m_name, m_nameSize) != 0)
- {
- qWarning("CarlaEngineOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, m_name);
- return 1;
- }
-
- // Get plugin id from message
- int pluginId = 0;
-
- if (std::isdigit(path[m_nameSize+2]))
- pluginId += path[m_nameSize+2]-'0';
-
- if (std::isdigit(path[m_nameSize+3]))
- pluginId += (path[m_nameSize+3]-'0')*10;
-
- if (pluginId < 0 || pluginId > engine->maxPluginNumber())
- {
- qCritical("CarlaEngineOsc::handleMessage() - failed to get plugin, wrong id '%i'", pluginId);
- return 1;
- }
-
- // Get plugin
- CarlaPlugin* const plugin = engine->getPluginUnchecked(pluginId);
-
- if (plugin == nullptr || plugin->id() != pluginId)
- {
- qWarning("CarlaEngineOsc::handleMessage() - invalid plugin id '%i', probably has been removed", pluginId);
- return 1;
- }
-
- // Get method from path, "/Carla/i/method"
- const int offset = (pluginId >= 10) ? 5 : 4;
- char method[32] = { 0 };
- strncpy(method, path + (m_nameSize + offset), 31);
-
- if (method[0] == '\0')
- {
- qWarning("CarlaEngineOsc::handleMessage(\"%s\", ...) - received message without method", path);
- return 1;
- }
-
- // Common OSC methods (DSSI and internal UIs)
- if (strcmp(method, "update") == 0)
- {
- const lo_address source = lo_message_get_source(msg);
- return handleMsgUpdate(plugin, argc, argv, types, source);
- }
- if (strcmp(method, "configure") == 0)
- return handleMsgConfigure(plugin, argc, argv, types);
- if (strcmp(method, "control") == 0)
- return handleMsgControl(plugin, argc, argv, types);
- if (strcmp(method, "program") == 0)
- return handleMsgProgram(plugin, argc, argv, types);
- if (strcmp(method, "midi") == 0)
- return handleMsgMidi(plugin, argc, argv, types);
- if (strcmp(method, "exiting") == 0)
- return handleMsgExiting(plugin);
-
-#ifndef BUILD_BRIDGE
- // Internal methods
- if (strcmp(method, "set_active") == 0)
- return handleMsgSetActive(plugin, argc, argv, types);
- if (strcmp(method, "set_drywet") == 0)
- return handleMsgSetDryWet(plugin, argc, argv, types);
- if (strcmp(method, "set_volume") == 0)
- return handleMsgSetVolume(plugin, argc, argv, types);
- if (strcmp(method, "set_balance_left") == 0)
- return handleMsgSetBalanceLeft(plugin, argc, argv, types);
- if (strcmp(method, "set_balance_right") == 0)
- return handleMsgSetBalanceRight(plugin, argc, argv, types);
- if (strcmp(method, "set_parameter_value") == 0)
- return handleMsgSetParameterValue(plugin, argc, argv, types);
- if (strcmp(method, "set_parameter_midi_cc") == 0)
- return handleMsgSetParameterMidiCC(plugin, argc, argv, types);
- if (strcmp(method, "set_parameter_midi_channel") == 0)
- return handleMsgSetParameterMidiChannel(plugin, argc, argv, types);
- if (strcmp(method, "set_program") == 0)
- return handleMsgSetProgram(plugin, argc, argv, types);
- if (strcmp(method, "set_midi_program") == 0)
- return handleMsgSetMidiProgram(plugin, argc, argv, types);
- if (strcmp(method, "note_on") == 0)
- return handleMsgNoteOn(plugin, argc, argv, types);
- if (strcmp(method, "note_off") == 0)
- return handleMsgNoteOff(plugin, argc, argv, types);
-
- // Plugin Bridges
- if ((plugin->hints() & PLUGIN_IS_BRIDGE) > 0 && strlen(method) > 11 && strncmp(method, "bridge_", 7) == 0)
- {
- if (strcmp(method+7, "set_inpeak") == 0)
- return handleMsgBridgeSetInPeak(plugin, argc, argv, types);
- if (strcmp(method+7, "set_outpeak") == 0)
- return handleMsgBridgeSetOutPeak(plugin, argc, argv, types);
- if (strcmp(method+7, "audio_count") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeAudioCount, argc, argv, types);
- if (strcmp(method+7, "midi_count") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeMidiCount, argc, argv, types);
- if (strcmp(method+7, "parameter_count") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeParameterCount, argc, argv, types);
- if (strcmp(method+7, "program_count") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeProgramCount, argc, argv, types);
- if (strcmp(method+7, "midi_program_count") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeMidiProgramCount, argc, argv, types);
- if (strcmp(method+7, "plugin_info") == 0)
- return plugin->setOscBridgeInfo(PluginBridgePluginInfo, argc, argv, types);
- if (strcmp(method+7, "parameter_info") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeParameterInfo, argc, argv, types);
- if (strcmp(method+7, "parameter_data") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeParameterData, argc, argv, types);
- if (strcmp(method+7, "parameter_ranges") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeParameterRanges, argc, argv, types);
- if (strcmp(method+7, "program_info") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeProgramInfo, argc, argv, types);
- if (strcmp(method+7, "midi_program_info") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeMidiProgramInfo, argc, argv, types);
- if (strcmp(method+7, "configure") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeConfigure, argc, argv, types);
- if (strcmp(method+7, "set_parameter_value") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetParameterValue, argc, argv, types);
- if (strcmp(method+7, "set_default_value") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetDefaultValue, argc, argv, types);
- if (strcmp(method+7, "set_program") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetProgram, argc, argv, types);
- if (strcmp(method+7, "set_midi_program") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetMidiProgram, argc, argv, types);
- if (strcmp(method+7, "set_custom_data") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetCustomData, argc, argv, types);
- if (strcmp(method+7, "set_chunk_data") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeSetChunkData, argc, argv, types);
- if (strcmp(method+7, "update") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeUpdateNow, argc, argv, types);
- if (strcmp(method+7, "error") == 0)
- return plugin->setOscBridgeInfo(PluginBridgeError, argc, argv, types);
- }
-#endif
-
- // Plugin-specific methods
-#ifdef WANT_LV2
- if (strcmp(method, "lv2_atom_transfer") == 0)
- return handleMsgLv2AtomTransfer(plugin, argc, argv, types);
- if (strcmp(method, "lv2_event_transfer") == 0)
- return handleMsgLv2EventTransfer(plugin, argc, argv, types);
-#endif
-
- qWarning("CarlaEngineOsc::handleMessage() - unsupported OSC method '%s'", method);
- return 1;
-}
-
-// -----------------------------------------------------------------------
-
-#ifndef BUILD_BRIDGE
-int CarlaEngineOsc::handleMsgRegister(const int argc, const lo_arg* const* const argv, const char* const types, const lo_address source)
-{
- qDebug("CarlaEngineOsc::handleMsgRegister()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");
-
- if (m_controlData.path)
- {
- qWarning("CarlaEngineOsc::handleMsgRegister() - OSC backend already registered to %s", m_controlData.path);
- return 1;
- }
-
- const char* const url = (const char*)&argv[0]->s;
- const char* host;
- const char* port;
-
- qDebug("CarlaEngineOsc::handleMsgRegister() - OSC backend registered to %s", url);
-
- host = lo_address_get_hostname(source);
- port = lo_address_get_port(source);
- m_controlData.source = lo_address_new_with_proto(LO_TCP, host, port);
-
- host = lo_url_get_hostname(url);
- port = lo_url_get_port(url);
- m_controlData.path = lo_url_get_path(url);
- m_controlData.target = lo_address_new_with_proto(LO_TCP, host, port);
-
- free((void*)host);
- free((void*)port);
-
- for (unsigned short i=0; i < engine->maxPluginNumber(); i++)
- {
- CarlaPlugin* const plugin = engine->getPluginUnchecked(i);
-
- if (plugin && plugin->enabled())
- plugin->registerToOscClient();
- }
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgUnregister()
-{
- qDebug("CarlaEngineOsc::handleMsgUnregister()");
-
- if (! m_controlData.path)
- {
- qWarning("CarlaEngineOsc::handleMsgUnregister() - OSC backend is not registered yet");
- return 1;
- }
-
- m_controlData.free();
- return 0;
-}
-#endif
-
-// -----------------------------------------------------------------------
-
-int CarlaEngineOsc::handleMsgUpdate(CARLA_ENGINE_OSC_HANDLE_ARGS2, const lo_address source)
-{
- qDebug("CarlaEngineOsc::handleMsgUpdate()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "s");
-
- const char* const url = (const char*)&argv[0]->s;
- plugin->updateOscData(source, url);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgConfigure(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgConfigure()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ss");
-
- const char* const key = (const char*)&argv[0]->s;
- const char* const value = (const char*)&argv[1]->s;
-
-#ifdef DEBUG
- qDebug("CarlaEngineOsc::handleMsgConfigure(\"%s\", \"%s\")", key, value);
-#endif
-
- plugin->setCustomData(CUSTOM_DATA_STRING, key, value, false);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgControl(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgControl()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if");
-
- const int rindex = argv[0]->i;
- const float value = argv[1]->f;
- plugin->setParameterValueByRIndex(rindex, value, false, true, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgProgram()");
-
- if (argc == 2)
- {
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");
-
- const uint32_t bank_id = argv[0]->i;
- const uint32_t program_id = argv[1]->i;
- plugin->setMidiProgramById(bank_id, program_id, false, true, true, true);
-
- return 0;
- }
- else
- {
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");
-
- const uint32_t program_id = argv[0]->i;
-
- if (program_id < plugin->programCount())
- {
- plugin->setProgram(program_id, false, true, true, true);
- return 0;
- }
-
- qCritical("CarlaEngineOsc::handleMsgProgram() - program_id '%i' out of bounds", program_id);
- }
-
- return 1;
-}
-
-int CarlaEngineOsc::handleMsgMidi(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgMidi()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "m");
-
- if (plugin->midiInCount() > 0)
- {
- const uint8_t* const data = argv[0]->m;
- uint8_t status = data[1];
- uint8_t channel = status & 0x0F;
-
- // Fix bad note-off
- if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0)
- status -= 0x10;
-
- if (MIDI_IS_STATUS_NOTE_OFF(status))
- {
- uint8_t note = data[2];
- plugin->sendMidiSingleNote(channel, note, 0, false, true, true);
- }
- else if (MIDI_IS_STATUS_NOTE_ON(status))
- {
- uint8_t note = data[2];
- uint8_t velo = data[3];
- plugin->sendMidiSingleNote(channel, note, velo, false, true, true);
- }
-
- return 0;
- }
-
- qWarning("CarlaEngineOsc::handleMsgMidi() - recived midi when plugin has no midi inputs");
- return 1;
-}
-
-int CarlaEngineOsc::handleMsgExiting(CARLA_ENGINE_OSC_HANDLE_ARGS1)
-{
- qDebug("CarlaEngineOsc::handleMsgExiting()");
-
- // TODO - check for non-UIs (dssi-vst) and set to -1 instead
- engine->callback(CALLBACK_SHOW_GUI, plugin->id(), 0, 0, 0.0, nullptr);
- plugin->freeOscData();
-
- return 0;
-}
-
-// -----------------------------------------------------------------------
-
-#ifndef BUILD_BRIDGE
-int CarlaEngineOsc::handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetActive()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");
-
- const bool active = (bool)argv[0]->i;
- plugin->setActive(active, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetDryWet()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");
-
- const float value = argv[0]->f;
- plugin->setDryWet(value, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetVolume()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");
-
- const float value = argv[0]->f;
- plugin->setVolume(value, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetBalanceLeft()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");
-
- const float value = argv[0]->f;
- plugin->setBalanceLeft(value, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetBalanceRight()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "f");
-
- const float value = argv[0]->f;
- plugin->setBalanceRight(value, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetParameterValue()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "if");
-
- const int32_t index = argv[0]->i;
- const float value = argv[1]->f;
- plugin->setParameterValue(index, value, true, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetParameterMidiCC()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");
-
- const int32_t index = argv[0]->i;
- const int32_t cc = argv[1]->i;
- plugin->setParameterMidiCC(index, cc, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetParameterMidiChannel()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");
-
- const int32_t index = argv[0]->i;
- const int32_t channel = argv[1]->i;
- plugin->setParameterMidiChannel(index, channel, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetProgram()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");
-
- const int32_t index = argv[0]->i;
- plugin->setProgram(index, true, false, true, true);
-
- // parameters might have changed, send all param values back
- if (m_controlData.target && index >= 0)
- {
- for (uint32_t i=0; i < plugin->parameterCount(); i++)
- engine->osc_send_control_set_parameter_value(plugin->id(), i, plugin->getParameterValue(i));
- }
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgSetMidiProgram()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(1, "i");
-
- const int32_t index = argv[0]->i;
- plugin->setMidiProgram(index, true, false, true, true);
-
- // parameters might have changed, send all param values back
- if (m_controlData.target && index >= 0)
- {
- for (uint32_t i=0; i < plugin->parameterCount(); i++)
- engine->osc_send_control_set_parameter_value(plugin->id(), i, plugin->getParameterValue(i));
- }
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgNoteOn()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(3, "iii");
-
- const int32_t channel = argv[0]->i;
- const int32_t note = argv[1]->i;
- const int32_t velo = argv[2]->i;
- plugin->sendMidiSingleNote(channel, note, velo, true, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- qDebug("CarlaEngineOsc::handleMsgNoteOff()");
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "ii");
-
- const int32_t channel = argv[0]->i;
- const int32_t note = argv[1]->i;
- plugin->sendMidiSingleNote(channel, note, 0, true, false, true);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgBridgeSetInPeak(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "id");
-
- const int32_t index = argv[0]->i;
- const double value = argv[1]->d;
- engine->setInputPeak(plugin->id(), index-1, value);
-
- return 0;
-}
-
-int CarlaEngineOsc::handleMsgBridgeSetOutPeak(CARLA_ENGINE_OSC_HANDLE_ARGS2)
-{
- CARLA_ENGINE_OSC_CHECK_OSC_TYPES(2, "id");
-
- const int32_t index = argv[0]->i;
- const double value = argv[1]->d;
- engine->setOutputPeak(plugin->id(), index-1, value);
-
- return 0;
-}
-#endif
-
-CARLA_BACKEND_END_NAMESPACE
diff --git a/c++/carla-engine/carla_engine_osc.hpp b/c++/carla-engine/carla_engine_osc.hpp
deleted file mode 100644
index 16d9812..0000000
--- a/c++/carla-engine/carla_engine_osc.hpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Carla Engine OSC
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_ENGINE_OSC_HPP
-#define CARLA_ENGINE_OSC_HPP
-
-#include "carla_backend.hpp"
-#include "carla_osc_utils.hpp"
-
-#define CARLA_ENGINE_OSC_HANDLE_ARGS1 CarlaPlugin* const plugin
-#define CARLA_ENGINE_OSC_HANDLE_ARGS2 CarlaPlugin* const plugin, const int argc, const lo_arg* const* const argv, const char* const types
-
-#define CARLA_ENGINE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
- /* check argument count */ \
- if (argc != argcToCompare) \
- { \
- qCritical("CarlaEngineOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
- return 1; \
- } \
- if (argc > 0) \
- { \
- /* check for nullness */ \
- if (! (types && typesToCompare)) \
- { \
- qCritical("CarlaEngineOsc::%s() - argument types are null", __FUNCTION__); \
- return 1; \
- } \
- /* check argument types */ \
- if (strcmp(types, typesToCompare) != 0) \
- { \
- qCritical("CarlaEngineOsc::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
- return 1; \
- } \
- }
-
-CARLA_BACKEND_START_NAMESPACE
-
-#if 0
-} // Fix editor indentation
-#endif
-
-class CarlaEngineOsc
-{
-public:
- CarlaEngineOsc(CarlaEngine* const engine);
- ~CarlaEngineOsc();
-
- void init(const char* const name);
- void idle();
- void close();
-
- // -------------------------------------------------------------------
-
-#ifndef BUILD_BRIDGE
- bool isControlRegistered() const
- {
- return bool(m_controlData.target);
- }
-
- const CarlaOscData* getControlData() const
- {
- return &m_controlData;
- }
-#endif
-
- const char* getServerPathTCP() const
- {
- return (const char*)m_serverPathTCP;
- }
-
- const char* getServerPathUDP() const
- {
- return (const char*)m_serverPathUDP;
- }
-
- // -------------------------------------------------------------------
-
-private:
- CarlaEngine* const engine;
-
- char* m_name;
- size_t m_nameSize;
-
- lo_server m_serverTCP;
- lo_server m_serverUDP;
- CarlaString m_serverPathTCP;
- CarlaString m_serverPathUDP;
-
-#ifndef BUILD_BRIDGE
- CarlaOscData m_controlData; // for carla-control
-#endif
-
- // -------------------------------------------------------------------
-
- int handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);
-
-#ifndef BUILD_BRIDGE
- int handleMsgRegister(const int argc, const lo_arg* const* const argv, const char* const types, const lo_address source);
- int handleMsgUnregister();
-#endif
-
- int handleMsgUpdate(CARLA_ENGINE_OSC_HANDLE_ARGS2, const lo_address source);
- int handleMsgConfigure(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgControl(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgMidi(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgExiting(CARLA_ENGINE_OSC_HANDLE_ARGS1);
-
-#ifndef BUILD_BRIDGE
- int handleMsgSetActive(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetDryWet(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetVolume(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetBalanceLeft(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetBalanceRight(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetParameterValue(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetParameterMidiCC(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetParameterMidiChannel(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgSetMidiProgram(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgNoteOn(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgNoteOff(CARLA_ENGINE_OSC_HANDLE_ARGS2);
-
- int handleMsgBridgeSetInPeak(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgBridgeSetOutPeak(CARLA_ENGINE_OSC_HANDLE_ARGS2);
-#endif
-
-#ifdef WANT_LV2
- int handleMsgLv2AtomTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2);
- int handleMsgLv2EventTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2);
-#endif
-
- // -----------------------------------------------------------------------
-
- static void osc_error_handlerTCP(const int num, const char* const msg, const char* const path)
- {
- qWarning("CarlaEngineOsc::osc_error_handlerTCP(%i, \"%s\", \"%s\")", num, msg, path);
- }
-
- static void osc_error_handlerUDP(const int num, const char* const msg, const char* const path)
- {
- qWarning("CarlaEngineOsc::osc_error_handlerUDP(%i, \"%s\", \"%s\")", num, msg, path);
- }
-
- static int osc_message_handler(const char* const path, const char* const types, lo_arg** const argv, const int argc, const lo_message msg, void* const userData)
- {
- CARLA_ASSERT(userData);
- if (CarlaEngineOsc* const _this_ = (CarlaEngineOsc*)userData)
- return _this_->handleMessage(path, argc, argv, types, msg);
- return 1;
- }
-};
-
-CARLA_BACKEND_END_NAMESPACE
-
-#endif // CARLA_ENGINE_OSC_HPP
diff --git a/c++/carla-engine/carla_engine_thread.cpp b/c++/carla-engine/carla_engine_thread.cpp
deleted file mode 100644
index bf4e79b..0000000
--- a/c++/carla-engine/carla_engine_thread.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Carla Engine Thread
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#include "carla_engine.hpp"
-#include "carla_plugin.hpp"
-
-CARLA_BACKEND_START_NAMESPACE
-
-// -----------------------------------------------------------------------
-
-CarlaEngineThread::CarlaEngineThread(CarlaEngine* const engine_, QObject* const parent)
- : QThread(parent),
- engine(engine_)
-{
- qDebug("CarlaEngineThread::CarlaEngineThread(%p, %p)", engine, parent);
- CARLA_ASSERT(engine);
-
- m_stopNow = true;
-}
-
-CarlaEngineThread::~CarlaEngineThread()
-{
- qDebug("CarlaEngineThread::~CarlaEngineThread()");
- CARLA_ASSERT(m_stopNow);
-}
-
-// -----------------------------------------------------------------------
-
-void CarlaEngineThread::startNow()
-{
- qDebug("CarlaEngineThread::startNow()");
- CARLA_ASSERT(m_stopNow);
-
- m_stopNow = false;
-
- start(QThread::HighPriority);
-}
-
-void CarlaEngineThread::stopNow()
-{
- qDebug("CarlaEngineThread::stopNow()");
-
- if (m_stopNow)
- return;
-
- m_stopNow = true;
-
- const ScopedLocker m(this);
-
- if (isRunning() && ! wait(200))
- {
- quit();
-
- if (isRunning() && ! wait(300))
- terminate();
- }
-}
-
-// -----------------------------------------------------------------------
-
-void CarlaEngineThread::run()
-{
- qDebug("CarlaEngineThread::run()");
- CARLA_ASSERT(engine->isRunning());
-
- bool oscRegisted, usesSingleThread;
- unsigned short i;
- double value;
-
- while (engine->isRunning() && ! m_stopNow)
- {
- const ScopedLocker m(this);
-#ifndef BUILD_BRIDGE
- oscRegisted = engine->isOscControlRegistered();
-#else
- oscRegisted = engine->isOscBridgeRegistered();
-#endif
-
- for (i=0; i < engine->maxPluginNumber(); i++)
- {
- CarlaPlugin* const plugin = engine->getPluginUnchecked(i);
-
- if (! (plugin && plugin->enabled()))
- continue;
-
-#ifndef BUILD_BRIDGE
- const unsigned short id = plugin->id();
-#endif
- usesSingleThread = (plugin->hints() & PLUGIN_USES_SINGLE_THREAD);
-
- // -------------------------------------------------------
- // Process postponed events
-
- if (! usesSingleThread)
- plugin->postEventsRun();
-
- if (oscRegisted || ! usesSingleThread)
- {
- // ---------------------------------------------------
- // Update parameter outputs
-
- for (uint32_t j=0; j < plugin->parameterCount(); j++)
- {
- if (! plugin->parameterIsOutput(j))
- continue;
-
- value = plugin->getParameterValue(j);
-
- // Update UI
- if (! usesSingleThread)
- plugin->uiParameterChange(j, value);
-
- // Update OSC engine client
- if (oscRegisted)
- {
-#ifdef BUILD_BRIDGE
- engine->osc_send_bridge_set_parameter_value(j, value);
-#else
- engine->osc_send_control_set_parameter_value(id, j, value);
-#endif
- }
- }
-
- // ---------------------------------------------------
- // Update OSC control client peaks
-
- if (oscRegisted)
- {
-#ifdef BUILD_BRIDGE
- engine->osc_send_peaks(plugin);
-#else
- engine->osc_send_peaks(plugin, id);
-#endif
- }
- }
- }
-
- engine->idleOsc();
- msleep(oscRegisted ? 40 : 50);
- }
-}
-
-CARLA_BACKEND_END_NAMESPACE
diff --git a/c++/carla-engine/carla_engine_thread.hpp b/c++/carla-engine/carla_engine_thread.hpp
deleted file mode 100644
index baceca5..0000000
--- a/c++/carla-engine/carla_engine_thread.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Carla Engine Thread
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifndef CARLA_ENGINE_THREAD_HPP
-#define CARLA_ENGINE_THREAD_HPP
-
-#include "carla_backend.hpp"
-
-#include
-#include
-
-CARLA_BACKEND_START_NAMESPACE
-
-#if 0
-} // Fix editor indentation
-#endif
-
-class CarlaEngineThread : public QThread
-{
-public:
- CarlaEngineThread(CarlaEngine* const engine, QObject* const parent = nullptr);
- ~CarlaEngineThread();
-
- void startNow();
- void stopNow();
-
- // ----------------------------------------------
-
-protected:
- void run();
-
- // ----------------------------------------------
-
-private:
- CarlaEngine* const engine;
-
- QMutex m_mutex;
- bool m_stopNow;
-
- // ----------------------------------------------
-
- class ScopedLocker
- {
- public:
- ScopedLocker(CarlaEngineThread* const thread)
- : mutex(&thread->m_mutex)
- {
- mutex->lock();
- }
-
- ~ScopedLocker()
- {
- mutex->unlock();
- }
-
- private:
- QMutex* const mutex;
- };
-};
-
-CARLA_BACKEND_END_NAMESPACE
-
-#endif // CARLA_ENGINE_THREAD_HPP
diff --git a/c++/carla-engine/jack.cpp b/c++/carla-engine/jack.cpp
deleted file mode 100644
index 2c56b70..0000000
--- a/c++/carla-engine/jack.cpp
+++ /dev/null
@@ -1,1149 +0,0 @@
-/*
- * Carla JACK Engine
- * Copyright (C) 2011-2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifdef CARLA_ENGINE_JACK
-
-#include "carla_engine.hpp"
-#include "carla_plugin.hpp"
-
-#include "carla_jackbridge.h"
-
-CARLA_BACKEND_START_NAMESPACE
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (JackAudio)
-
-class CarlaEngineJackAudioPort : public CarlaEngineAudioPort
-{
-public:
- CarlaEngineJackAudioPort(const bool isInput, const ProcessMode processMode, jack_client_t* const client, jack_port_t* const port)
- : CarlaEngineAudioPort(isInput, processMode),
- m_client(client),
- m_port(port)
- {
- qDebug("CarlaEngineJackAudioPort::CarlaEngineJackAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-
- if (processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- CARLA_ASSERT(m_client && m_port);
- else
- CARLA_ASSERT(! (m_client || m_port));
- }
-
- ~CarlaEngineJackAudioPort()
- {
- qDebug("CarlaEngineJackAudioPort::~CarlaEngineJackAudioPort()");
-
- if (m_client && m_port)
- jackbridge_port_unregister(m_client, m_port);
- }
-
- void initBuffer(CarlaEngine* const engine)
- {
- if (! m_port)
- return CarlaEngineAudioPort::initBuffer(engine);
-
- buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize());
- }
-
- float* getBuffer() const
- {
- return (float*)buffer;
- }
-
-private:
- jack_client_t* const m_client;
- jack_port_t* const m_port;
-
- friend class CarlaEngineJack;
-};
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (JackControl)
-
-class CarlaEngineJackControlPort : public CarlaEngineControlPort
-{
-public:
- CarlaEngineJackControlPort(const bool isInput, const ProcessMode processMode, jack_client_t* const client, jack_port_t* const port)
- : CarlaEngineControlPort(isInput, processMode),
- m_client(client),
- m_port(port)
- {
- qDebug("CarlaEngineJackControlPort::CarlaEngineJackControlPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-
- if (processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- CARLA_ASSERT(m_client && m_port);
- else
- CARLA_ASSERT(! (m_client || m_port));
- }
-
- ~CarlaEngineJackControlPort()
- {
- qDebug("CarlaEngineJackControlPort::~CarlaEngineJackControlPort()");
-
- if (m_client && m_port)
- jackbridge_port_unregister(m_client, m_port);
- }
-
- void initBuffer(CarlaEngine* const engine)
- {
- if (! m_port)
- return CarlaEngineControlPort::initBuffer(engine);
-
- CARLA_ASSERT(engine);
-
- buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize());
-
- if (! isInput)
- jackbridge_midi_clear_buffer(buffer);
- }
-
- uint32_t getEventCount()
- {
- if (! m_port)
- return CarlaEngineControlPort::getEventCount();
-
- if (! isInput)
- return 0;
-
- CARLA_ASSERT(buffer);
-
- return jackbridge_midi_get_event_count(buffer);
- }
-
- const CarlaEngineControlEvent* getEvent(const uint32_t index)
- {
- if (! m_port)
- return CarlaEngineControlPort::getEvent(index);
-
- if (! isInput)
- return nullptr;
-
- CARLA_ASSERT(buffer);
-
- static jack_midi_event_t jackEvent;
- static CarlaEngineControlEvent carlaEvent;
-
- if (jackbridge_midi_event_get(&jackEvent, buffer, index) != 0)
- return nullptr;
-
- memset(&carlaEvent, 0, sizeof(CarlaEngineControlEvent));
-
- uint8_t midiStatus = jackEvent.buffer[0];
- uint8_t midiChannel = midiStatus & 0x0F;
-
- carlaEvent.time = jackEvent.time;
- carlaEvent.channel = midiChannel;
-
- if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
- {
- uint8_t midiControl = jackEvent.buffer[1];
-
- if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
- {
- uint8_t midiBank = jackEvent.buffer[2];
- carlaEvent.type = CarlaEngineMidiBankChangeEvent;
- carlaEvent.value = midiBank;
- }
- else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
- {
- carlaEvent.type = CarlaEngineAllSoundOffEvent;
- }
- else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
- {
- carlaEvent.type = CarlaEngineAllNotesOffEvent;
- }
- else
- {
- uint8_t midiValue = jackEvent.buffer[2];
- carlaEvent.type = CarlaEngineParameterChangeEvent;
- carlaEvent.parameter = midiControl;
- carlaEvent.value = double(midiValue)/127;
- }
-
- return &carlaEvent;
- }
- if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
- {
- uint8_t midiProgram = jackEvent.buffer[1];
- carlaEvent.type = CarlaEngineMidiProgramChangeEvent;
- carlaEvent.value = midiProgram;
-
- return &carlaEvent;
- }
-
- return nullptr;
- }
-
- void writeEvent(const CarlaEngineControlEventType type, const uint32_t time, const uint8_t channel, const uint16_t parameter, const double value)
- {
- if (! m_port)
- return CarlaEngineControlPort::writeEvent(type, time, channel, parameter, value);
-
- if (isInput)
- return;
-
- CARLA_ASSERT(buffer);
- CARLA_ASSERT(type != CarlaEngineNullEvent);
-
- if (type == CarlaEngineNullEvent)
- return;
- if (type == CarlaEngineParameterChangeEvent)
- CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter));
-
- uint8_t data[3] = { 0 };
-
- switch (type)
- {
- case CarlaEngineNullEvent:
- break;
- case CarlaEngineParameterChangeEvent:
- data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
- data[1] = parameter;
- data[2] = value * 127;
- jackbridge_midi_event_write(buffer, time, data, 3);
- break;
- case CarlaEngineMidiBankChangeEvent:
- data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
- data[1] = MIDI_CONTROL_BANK_SELECT;
- data[2] = value;
- jackbridge_midi_event_write(buffer, time, data, 3);
- break;
- case CarlaEngineMidiProgramChangeEvent:
- data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel;
- data[1] = value;
- jackbridge_midi_event_write(buffer, time, data, 2);
- break;
- case CarlaEngineAllSoundOffEvent:
- data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
- data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
- jackbridge_midi_event_write(buffer, time, data, 2);
- break;
- case CarlaEngineAllNotesOffEvent:
- data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
- data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
- jackbridge_midi_event_write(buffer, time, data, 2);
- break;
- }
- }
-
-private:
- jack_client_t* const m_client;
- jack_port_t* const m_port;
-};
-
-// -------------------------------------------------------------------------------------------------------------------
-// Engine port (JackMIDI)
-
-class CarlaEngineJackMidiPort : public CarlaEngineMidiPort
-{
-public:
- CarlaEngineJackMidiPort(const bool isInput, const ProcessMode processMode, jack_client_t* const client, jack_port_t* const port)
- : CarlaEngineMidiPort(isInput, processMode),
- m_client(client),
- m_port(port)
- {
- qDebug("CarlaEngineJackMidiPort::CarlaEngineJackMidiPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));
-
- if (processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- CARLA_ASSERT(m_client && m_port);
- else
- CARLA_ASSERT(! (m_client || m_port));
- }
-
- ~CarlaEngineJackMidiPort()
- {
- qDebug("CarlaEngineJackMidiPort::~CarlaEngineJackMidiPort()");
-
- if (m_client && m_port)
- jackbridge_port_unregister(m_client, m_port);
- }
-
- void initBuffer(CarlaEngine* const engine)
- {
- if (! m_port)
- return CarlaEngineMidiPort::initBuffer(engine);
-
- CARLA_ASSERT(engine);
-
- buffer = jackbridge_port_get_buffer(m_port, engine->getBufferSize());
-
- if (! isInput)
- jackbridge_midi_clear_buffer(buffer);
- }
-
- uint32_t getEventCount()
- {
- if (! m_port)
- return CarlaEngineMidiPort::getEventCount();
-
- if (! isInput)
- return 0;
-
- CARLA_ASSERT(buffer);
-
- return jackbridge_midi_get_event_count(buffer);
- }
-
- const CarlaEngineMidiEvent* getEvent(const uint32_t index)
- {
- if (! m_port)
- return CarlaEngineMidiPort::getEvent(index);
-
- if (! isInput)
- return nullptr;
-
- CARLA_ASSERT(buffer);
-
- static jack_midi_event_t jackEvent;
- static CarlaEngineMidiEvent carlaEvent;
-
- if (jackbridge_midi_event_get(&jackEvent, buffer, index) == 0 && jackEvent.size <= 4)
- {
- carlaEvent.time = jackEvent.time;
- carlaEvent.size = jackEvent.size;
- memcpy(carlaEvent.data, jackEvent.buffer, jackEvent.size);
- return &carlaEvent;
- }
-
- return nullptr;
- }
-
- void writeEvent(const uint32_t time, const uint8_t* const data, const uint8_t size)
- {
- if (! m_port)
- return CarlaEngineMidiPort::writeEvent(time, data, size);
-
- if (isInput)
- return;
-
- CARLA_ASSERT(buffer);
- CARLA_ASSERT(data);
- CARLA_ASSERT(size > 0);
-
- jackbridge_midi_event_write(buffer, time, data, size);
- }
-
-private:
- jack_client_t* const m_client;
- jack_port_t* const m_port;
-};
-
-// -------------------------------------------------------------------------------------------------------------------
-// Jack Engine client
-
-class CarlaEngineJackClient : public CarlaEngineClient
-{
-public:
- CarlaEngineJackClient(jack_client_t* const client, const CarlaEngineType engineType, const ProcessMode processMode)
- : CarlaEngineClient(engineType, processMode),
- m_client(client),
- m_usesClient(processMode == PROCESS_MODE_SINGLE_CLIENT || processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- if (m_usesClient)
- CARLA_ASSERT(m_client);
- else
- CARLA_ASSERT(! m_client);
- }
-
- ~CarlaEngineJackClient()
- {
- if (processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- if (m_client)
- jackbridge_client_close(m_client);
- }
- }
-
- void activate()
- {
- if (processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- if (m_client && ! isActive())
- jackbridge_activate(m_client);
- }
-
- CarlaEngineClient::activate();
- }
-
- void deactivate()
- {
- if (processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- if (m_client && isActive())
- jackbridge_deactivate(m_client);
- }
-
- CarlaEngineClient::deactivate();
- }
-
- bool isOk() const
- {
- if (m_usesClient)
- return bool(m_client);
-
- return CarlaEngineClient::isOk();
- }
-
- void setLatency(const uint32_t samples)
- {
- CarlaEngineClient::setLatency(samples);
-
- if (m_usesClient)
- jackbridge_recompute_total_latencies(m_client);
- }
-
- const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput)
- {
- qDebug("CarlaJackEngineClient::addPort(%i, \"%s\", %s)", portType, name, bool2str(isInput));
-
- jack_port_t* port = nullptr;
-
- // Create Jack port if needed
- if (m_usesClient)
- {
- switch (portType)
- {
- case CarlaEnginePortTypeNull:
- break;
- case CarlaEnginePortTypeAudio:
- port = jackbridge_port_register(m_client, name, JACK_DEFAULT_AUDIO_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
- break;
- case CarlaEnginePortTypeControl:
- case CarlaEnginePortTypeMIDI:
- port = jackbridge_port_register(m_client, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
- break;
- }
- }
-
- // Create Engine port
- switch (portType)
- {
- case CarlaEnginePortTypeNull:
- break;
- case CarlaEnginePortTypeAudio:
- return new CarlaEngineJackAudioPort(isInput, processMode, m_client, port);
- case CarlaEnginePortTypeControl:
- return new CarlaEngineJackControlPort(isInput, processMode, m_client, port);
- case CarlaEnginePortTypeMIDI:
- return new CarlaEngineJackMidiPort(isInput, processMode, m_client, port);
- }
-
- qCritical("CarlaJackEngineClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput));
- return nullptr;
- }
-
-private:
- jack_client_t* const m_client;
- const bool m_usesClient;
-};
-
-// -------------------------------------------------------------------------------------------------------------------
-// Jack Engine
-
-class CarlaEngineJack : public CarlaEngine
-{
-public:
- CarlaEngineJack()
- : CarlaEngine()
-#ifndef BUILD_BRIDGE
-# ifdef Q_COMPILER_INITIALIZER_LISTS
- , m_rackPorts{nullptr}
-# endif
-#endif
- {
- qDebug("CarlaEngineJack::CarlaEngineJack()");
-
- m_client = nullptr;
- m_state = JackTransportStopped;
- m_freewheel = false;
-
- memset(&m_pos, 0, sizeof(jack_position_t));
-
-#ifdef BUILD_BRIDGE
- hasQuit = false;
-#else
-# ifndef Q_COMPILER_INITIALIZER_LISTS
- for (int i=0; i < rackPortCount; i++)
- m_rackPorts[i] = nullptr;
-# endif
-#endif
- }
-
- ~CarlaEngineJack()
- {
- qDebug("CarlaEngineJack::~CarlaEngineJack()");
- CARLA_ASSERT(! m_client);
- }
-
- // -------------------------------------------------------------------
- // Maximum values
-
- int maxClientNameSize()
- {
-#ifndef BUILD_BRIDGE
- if (options.processMode == PROCESS_MODE_SINGLE_CLIENT || options.processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
-#endif
- return jackbridge_client_name_size() - 3; // reserve space for "_2" forced-stereo ports
-
- return CarlaEngine::maxClientNameSize();
- }
-
- int maxPortNameSize()
- {
-#ifndef BUILD_BRIDGE
- if (options.processMode == PROCESS_MODE_SINGLE_CLIENT || options.processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
-#endif
- return jackbridge_port_name_size();
-
- return CarlaEngine::maxPortNameSize();
- }
-
- // -------------------------------------------------------------------
- // Virtual, per-engine type calls
-
- bool init(const char* const clientName)
- {
- qDebug("CarlaEngineJack::init(\"%s\")", clientName);
-
- m_state = JackTransportStopped;
- m_freewheel = false;
-
-#ifndef BUILD_BRIDGE
- m_client = jackbridge_client_open(clientName, JackNullOption, nullptr);
-
- if (m_client)
- {
- bufferSize = jackbridge_get_buffer_size(m_client);
- sampleRate = jackbridge_get_sample_rate(m_client);
-
- jackbridge_set_buffer_size_callback(m_client, carla_jack_bufsize_callback, this);
- jackbridge_set_sample_rate_callback(m_client, carla_jack_srate_callback, this);
- jackbridge_set_freewheel_callback(m_client, carla_jack_freewheel_callback, this);
- jackbridge_set_process_callback(m_client, carla_jack_process_callback, this);
- jackbridge_set_latency_callback(m_client, carla_jack_latency_callback, this);
- jackbridge_on_shutdown(m_client, carla_jack_shutdown_callback, this);
-
- if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- m_rackPorts[rackPortAudioIn1] = jackbridge_port_register(m_client, "in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
- m_rackPorts[rackPortAudioIn2] = jackbridge_port_register(m_client, "in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
- m_rackPorts[rackPortAudioOut1] = jackbridge_port_register(m_client, "out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- m_rackPorts[rackPortAudioOut2] = jackbridge_port_register(m_client, "out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
- m_rackPorts[rackPortControlIn] = jackbridge_port_register(m_client, "control-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
- m_rackPorts[rackPortControlOut] = jackbridge_port_register(m_client, "control-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
- m_rackPorts[rackPortMidiIn] = jackbridge_port_register(m_client, "midi-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
- m_rackPorts[rackPortMidiOut] = jackbridge_port_register(m_client, "midi-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
- }
-
- if (jackbridge_activate(m_client) == 0)
- {
- name = jackbridge_get_client_name(m_client);
- name.toBasic();
-
- CarlaEngine::init(name);
- return true;
- }
- else
- {
- setLastError("Failed to activate the JACK client");
- m_client = nullptr;
- }
- }
- else
- setLastError("Failed to create new JACK client");
-
- return false;
-#else
- // open temp client to get initial buffer-size and sample-rate values
- if (bufferSize == 0 || sampleRate == 0.0)
- {
- m_client = jackbridge_client_open(clientName, JackNullOption, nullptr);
-
- if (m_client)
- {
- bufferSize = jackbridge_get_buffer_size(m_client);
- sampleRate = jackbridge_get_sample_rate(m_client);
-
- jackbridge_client_close(m_client);
- m_client = nullptr;
- }
- }
-
- name = clientName;
- name.toBasic();
-
- CarlaEngine::init(name);
- return true;
-#endif
- }
-
- bool close()
- {
- qDebug("CarlaEngineJack::close()");
- CarlaEngine::close();
-
-#ifdef BUILD_BRIDGE
- hasQuit = true;
- m_client = nullptr;
- return true;
-#else
- if (jackbridge_deactivate(m_client) == 0)
- {
- if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortAudioIn1]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortAudioIn2]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortAudioOut1]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortAudioOut2]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortControlIn]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortControlOut]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortMidiIn]);
- jackbridge_port_unregister(m_client, m_rackPorts[rackPortMidiOut]);
- }
-
- if (jackbridge_client_close(m_client) == 0)
- {
- m_client = nullptr;
- return true;
- }
- else
- setLastError("Failed to close the JACK client");
- }
- else
- setLastError("Failed to deactivate the JACK client");
-
- m_client = nullptr;
-#endif
- return false;
- }
-
- bool isRunning() const
- {
-#ifdef BUILD_BRIDGE
- return bool(m_client || ! hasQuit);
-#else
- return bool(m_client);
-#endif
- }
-
- bool isOffline() const
- {
- return m_freewheel;
- }
-
- CarlaEngineType type() const
- {
- return CarlaEngineTypeJack;
- }
-
- CarlaEngineClient* addClient(CarlaPlugin* const plugin)
- {
- jack_client_t* client = nullptr;
-
-#ifdef BUILD_BRIDGE
- client = m_client = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);
-
- bufferSize = jackbridge_get_buffer_size(client);
- sampleRate = jackbridge_get_sample_rate(client);
-
- jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
- jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
- jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
- jackbridge_set_process_callback(client, carla_jack_process_callback, this);
- jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
- jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
-#else
- if (options.processMode == PROCESS_MODE_SINGLE_CLIENT)
- {
- client = m_client;
- }
- else if (options.processMode == PROCESS_MODE_MULTIPLE_CLIENTS)
- {
- client = jackbridge_client_open(plugin->name(), JackNullOption, nullptr);
- jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin);
- jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin);
- }
-#endif
-
-#ifdef BUILD_BRIDGE
- return new CarlaEngineJackClient(client, CarlaEngineTypeJack, PROCESS_MODE_MULTIPLE_CLIENTS);
-#else
- return new CarlaEngineJackClient(client, CarlaEngineTypeJack, options.processMode);
-#endif
- }
-
- // -------------------------------------
-
-protected:
- void handleJackBufferSizeCallback(const uint32_t newBufferSize)
- {
- bufferSize = newBufferSize;
-
-#ifndef BUILD_BRIDGE
- if (options.processHighPrecision)
- return;
-#endif
-
- bufferSizeChanged(newBufferSize);
- }
-
- void handleJackSampleRateCallback(const double newSampleRate)
- {
- sampleRate = newSampleRate;
- }
-
- void handleJackFreewheelCallback(const bool isFreewheel)
- {
- m_freewheel = isFreewheel;
- }
-
- void handleJackProcessCallback(const uint32_t nframes)
- {
-#ifndef BUILD_BRIDGE
- if (maxPluginNumber() == 0)
- return;
-#endif
-
- m_pos.unique_1 = m_pos.unique_2 + 1; // invalidate
- m_state = jackbridge_transport_query(m_client, &m_pos);
-
- timeInfo.playing = (m_state != JackTransportStopped);
-
- if (m_pos.unique_1 == m_pos.unique_2)
- {
- timeInfo.frame = m_pos.frame;
- timeInfo.time = m_pos.usecs;
-
- if (m_pos.valid & JackPositionBBT)
- {
- timeInfo.valid = CarlaEngineTimeBBT;
- timeInfo.bbt.bar = m_pos.bar;
- timeInfo.bbt.beat = m_pos.beat;
- timeInfo.bbt.tick = m_pos.tick;
- timeInfo.bbt.bar_start_tick = m_pos.bar_start_tick;
- timeInfo.bbt.beats_per_bar = m_pos.beats_per_bar;
- timeInfo.bbt.beat_type = m_pos.beat_type;
- timeInfo.bbt.ticks_per_beat = m_pos.ticks_per_beat;
- timeInfo.bbt.beats_per_minute = m_pos.beats_per_minute;
- }
- else
- timeInfo.valid = 0;
- }
- else
- {
- timeInfo.frame = 0;
- timeInfo.valid = 0;
- }
-
-#ifndef BUILD_BRIDGE
- if (options.processMode == PROCESS_MODE_SINGLE_CLIENT)
- {
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-#else
- CarlaPlugin* const plugin = getPluginUnchecked(0);
-#endif
-
- if (plugin && plugin->enabled())
- {
- processLock();
- plugin->initBuffers();
- processPlugin(plugin, nframes);
- processUnlock();
- }
-#ifndef BUILD_BRIDGE
- }
- }
- else if (options.processMode == PROCESS_MODE_CONTINUOUS_RACK)
- {
- // get buffers from jack
- float* audioIn1 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioIn1], nframes);
- float* audioIn2 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioIn2], nframes);
- float* audioOut1 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioOut1], nframes);
- float* audioOut2 = (float*)jackbridge_port_get_buffer(m_rackPorts[rackPortAudioOut2], nframes);
- void* controlIn = jackbridge_port_get_buffer(m_rackPorts[rackPortControlIn], nframes);
- void* controlOut = jackbridge_port_get_buffer(m_rackPorts[rackPortControlOut], nframes);
- void* midiIn = jackbridge_port_get_buffer(m_rackPorts[rackPortMidiIn], nframes);
- void* midiOut = jackbridge_port_get_buffer(m_rackPorts[rackPortMidiOut], nframes);
-
- // assert buffers
- CARLA_ASSERT(audioIn1);
- CARLA_ASSERT(audioIn2);
- CARLA_ASSERT(audioOut1);
- CARLA_ASSERT(audioOut2);
- CARLA_ASSERT(controlIn);
- CARLA_ASSERT(controlOut);
- CARLA_ASSERT(midiIn);
- CARLA_ASSERT(midiOut);
-
- // create audio buffers
- float* inBuf[2] = { audioIn1, audioIn2 };
- float* outBuf[2] = { audioOut1, audioOut2 };
-
- // initialize control input
- memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*MAX_CONTROL_EVENTS);
- {
- jack_midi_event_t jackEvent;
- const uint32_t jackEventCount = jackbridge_midi_get_event_count(controlIn);
-
- uint32_t carlaEventIndex = 0;
-
- for (uint32_t jackEventIndex=0; jackEventIndex < jackEventCount; jackEventIndex++)
- {
- if (jackbridge_midi_event_get(&jackEvent, controlIn, jackEventIndex) != 0)
- continue;
-
- CarlaEngineControlEvent* const carlaEvent = &rackControlEventsIn[carlaEventIndex++];
-
- const uint8_t midiStatus = jackEvent.buffer[0];
- const uint8_t midiChannel = midiStatus & 0x0F;
-
- carlaEvent->time = jackEvent.time;
- carlaEvent->channel = midiChannel;
-
- if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
- {
- const uint8_t midiControl = jackEvent.buffer[1];
-
- if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
- {
- const uint8_t midiBank = jackEvent.buffer[2];
- carlaEvent->type = CarlaEngineMidiBankChangeEvent;
- carlaEvent->value = midiBank;
- }
- else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF)
- {
- carlaEvent->type = CarlaEngineAllSoundOffEvent;
- }
- else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF)
- {
- carlaEvent->type = CarlaEngineAllNotesOffEvent;
- }
- else
- {
- const uint8_t midiValue = jackEvent.buffer[2];
- carlaEvent->type = CarlaEngineParameterChangeEvent;
- carlaEvent->parameter = midiControl;
- carlaEvent->value = double(midiValue)/127;
- }
- }
- else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
- {
- const uint8_t midiProgram = jackEvent.buffer[1];
- carlaEvent->type = CarlaEngineMidiProgramChangeEvent;
- carlaEvent->value = midiProgram;
- }
- }
- }
-
- // initialize midi input
- memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*MAX_MIDI_EVENTS);
- {
- uint32_t i = 0, j = 0;
- jack_midi_event_t jackEvent;
-
- while (jackbridge_midi_event_get(&jackEvent, midiIn, j++) == 0)
- {
- if (i == MAX_MIDI_EVENTS)
- 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;
- }
- }
- }
-
- // process rack
- processRack(inBuf, outBuf, nframes);
-
- // output control
- {
- jackbridge_midi_clear_buffer(controlOut);
-
- for (unsigned short i=0; i < MAX_CONTROL_EVENTS; i++)
- {
- CarlaEngineControlEvent* const event = &rackControlEventsOut[i];
-
- if (event->type == CarlaEngineParameterChangeEvent && MIDI_IS_CONTROL_BANK_SELECT(event->parameter))
- event->type = CarlaEngineMidiBankChangeEvent;
-
- uint8_t data[4] = { 0 };
-
- switch (event->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);
- 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);
- break;
- }
- }
- }
-
- // output midi
- {
- jackbridge_midi_clear_buffer(midiOut);
-
- for (unsigned short i=0; i < MAX_MIDI_EVENTS; i++)
- {
- if (rackMidiEventsOut[i].size == 0)
- break;
-
- jackbridge_midi_event_write(midiOut, rackMidiEventsOut[i].time, rackMidiEventsOut[i].data, rackMidiEventsOut[i].size);
- }
- }
- }
-#endif
- }
-
- void handleJackLatencyCallback(const jack_latency_callback_mode_t mode)
- {
-#ifndef BUILD_BRIDGE
- if (options.processMode != PROCESS_MODE_SINGLE_CLIENT)
- return;
-#endif
-
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-
- if (plugin && plugin->enabled())
- latencyPlugin(plugin, mode);
- }
- }
-
- void handleJackShutdownCallback()
- {
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-
- if (plugin)
- plugin->x_client = nullptr;
- }
-
- m_client = nullptr;
- callback(CALLBACK_QUIT, 0, 0, 0, 0.0, nullptr);
- }
-
- // -------------------------------------
-
-private:
- jack_client_t* m_client;
- jack_transport_state_t m_state;
- jack_position_t m_pos;
- bool m_freewheel;
-
- // -------------------------------------
-
-#ifdef BUILD_BRIDGE
- bool hasQuit;
-#else
- enum RackPorts {
- rackPortAudioIn1 = 0,
- rackPortAudioIn2 = 1,
- rackPortAudioOut1 = 2,
- rackPortAudioOut2 = 3,
- rackPortControlIn = 4,
- rackPortControlOut = 5,
- rackPortMidiIn = 6,
- rackPortMidiOut = 7,
- rackPortCount = 8
- };
-
- jack_port_t* m_rackPorts[rackPortCount];
-#endif
-
- // -------------------------------------
-
- static void processPlugin(CarlaPlugin* const p, const uint32_t nframes)
- {
- float* inBuffer[p->aIn.count];
- float* outBuffer[p->aOut.count];
-
- for (uint32_t i=0; i < p->aIn.count; i++)
- inBuffer[i] = ((CarlaEngineJackAudioPort*)p->aIn.ports[i])->getBuffer();
-
- for (uint32_t i=0; i < p->aOut.count; i++)
- outBuffer[i] = ((CarlaEngineJackAudioPort*)p->aOut.ports[i])->getBuffer();
-
- if (p->m_processHighPrecision)
- {
- float* inBuffer2[p->aIn.count];
- float* outBuffer2[p->aOut.count];
-
- for (uint32_t i=0, j; i < nframes; i += 8)
- {
- for (j=0; j < p->aIn.count; j++)
- inBuffer2[j] = inBuffer[j] + i;
-
- for (j=0; j < p->aOut.count; j++)
- outBuffer2[j] = outBuffer[j] + i;
-
- p->process(inBuffer2, outBuffer2, 8, i);
- }
- }
- else
- p->process(inBuffer, outBuffer, nframes);
- }
-
- static void latencyPlugin(CarlaPlugin* const p, jack_latency_callback_mode_t mode)
- {
- jack_latency_range_t range;
- uint32_t pluginLatency = p->x_client->getLatency();
-
- if (pluginLatency == 0)
- return;
-
- if (mode == JackCaptureLatency)
- {
- for (uint32_t i=0; i < p->aIn.count; i++)
- {
- uint aOutI = (i >= p->aOut.count) ? p->aOut.count : i;
- jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)p->aIn.ports[i])->m_port;
- jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)p->aOut.ports[aOutI])->m_port;
-
- jackbridge_port_get_latency_range(portIn, mode, &range);
- range.min += pluginLatency;
- range.max += pluginLatency;
- jackbridge_port_set_latency_range(portOut, mode, &range);
- }
- }
- else
- {
- for (uint32_t i=0; i < p->aOut.count; i++)
- {
- uint aInI = (i >= p->aIn.count) ? p->aIn.count : i;
- jack_port_t* const portIn = ((CarlaEngineJackAudioPort*)p->aIn.ports[aInI])->m_port;
- jack_port_t* const portOut = ((CarlaEngineJackAudioPort*)p->aOut.ports[i])->m_port;
-
- jackbridge_port_get_latency_range(portOut, mode, &range);
- range.min += pluginLatency;
- range.max += pluginLatency;
- jackbridge_port_set_latency_range(portIn, mode, &range);
- }
- }
- }
-
- // -------------------------------------
-
- static int carla_jack_srate_callback(jack_nframes_t newSampleRate, void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackSampleRateCallback(newSampleRate);
- return 0;
- }
-
- static int carla_jack_bufsize_callback(jack_nframes_t newBufferSize, void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackBufferSizeCallback(newBufferSize);
- return 0;
- }
-
- static void carla_jack_freewheel_callback(int starting, void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackFreewheelCallback(bool(starting));
- }
-
- static int carla_jack_process_callback(jack_nframes_t nframes, void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackProcessCallback(nframes);
- return 0;
- }
-
- static void carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackLatencyCallback(mode);
- }
-
- static void carla_jack_shutdown_callback(void* arg)
- {
- CarlaEngineJack* const _this_ = (CarlaEngineJack*)arg;
- _this_->handleJackShutdownCallback();
- }
-
- // -------------------------------------
-
- static int carla_jack_process_callback_plugin(jack_nframes_t nframes, void* arg)
- {
- CarlaPlugin* const plugin = (CarlaPlugin*)arg;
-
- if (plugin && plugin->enabled())
- {
- plugin->engineProcessLock();
- plugin->initBuffers();
- processPlugin(plugin, nframes);
- plugin->engineProcessUnlock();
- }
-
- return 0;
- }
-
- static void carla_jack_latency_callback_plugin(jack_latency_callback_mode_t mode, void* arg)
- {
- CarlaPlugin* const plugin = (CarlaPlugin*)arg;
-
- if (plugin && plugin->enabled())
- latencyPlugin(plugin, mode);
- }
-};
-
-// -----------------------------------------
-
-CarlaEngine* CarlaEngine::newJack()
-{
- return new CarlaEngineJack();
-}
-
-// -----------------------------------------
-
-CARLA_BACKEND_END_NAMESPACE
-
-#endif // CARLA_ENGINE_JACK
diff --git a/c++/carla-engine/plugin.cpp b/c++/carla-engine/plugin.cpp
deleted file mode 100644
index 112082b..0000000
--- a/c++/carla-engine/plugin.cpp
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Carla Plugin Engine
- * Copyright (C) 2012 Filipe Coelho
- *
- * 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 COPYING file
- */
-
-#ifdef CARLA_ENGINE_PLUGIN
-
-#include "carla_engine.hpp"
-#include "carla_plugin.hpp"
-
-#include "DistrhoPlugin.h"
-
-CARLA_BACKEND_START_NAMESPACE
-
-// -----------------------------------------
-// Parameters
-
-static const unsigned char paramMap[] = {
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
- 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
-};
-
-static const unsigned int paramVolume = 5;
-static const unsigned int paramBalance = 6;
-static const unsigned int paramPan = 8;
-
-static const unsigned int paramCount = sizeof(paramMap);
-static const unsigned int programCount = 128;
-
-// -------------------------------------------------------------------------------------------------------------------
-// Plugin Engine client
-
-class CarlaEnginePluginClient : public CarlaEngineClient
-{
-public:
- CarlaEnginePluginClient(const CarlaEngineType engineType, const ProcessMode processMode)
- : CarlaEngineClient(engineType, processMode)
- {
- }
-
- ~CarlaEnginePluginClient()
- {
- }
-
- const CarlaEngineBasePort* addPort(const CarlaEnginePortType portType, const char* const name, const bool isInput)
- {
- qDebug("CarlaEnginePluginClient::addPort(%i, \"%s\", %s)", portType, name, bool2str(isInput));
-
- switch (portType)
- {
- case CarlaEnginePortTypeNull:
- break;
- case CarlaEnginePortTypeAudio:
- return new CarlaEngineAudioPort(isInput, processMode);
- case CarlaEnginePortTypeControl:
- return new CarlaEngineControlPort(isInput, processMode);
- case CarlaEnginePortTypeMIDI:
- return new CarlaEngineMidiPort(isInput, processMode);
- }
-
- qCritical("CarlaEnginePluginClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput));
- return nullptr;
- }
-};
-
-// -----------------------------------------
-
-class CarlaEnginePlugin : public CarlaEngine,
- public DISTRHO::Plugin
-{
-public:
- short idZyn;
-
- CarlaEnginePlugin()
- : CarlaEngine(),
- DISTRHO::Plugin(paramCount, programCount, 0)
- {
- qDebug("CarlaEnginePlugin::CarlaEnginePlugin()");
-
- // init parameters
- for (unsigned int i=0; i < paramCount; i++)
- paramBuffers[i] = 0.0f;
-
- paramBuffers[paramVolume] = 100.0f;
- paramBuffers[paramBalance] = 63.5f;
- paramBuffers[paramPan] = 63.5f;
-
- memcpy(prevParamBuffers, paramBuffers, sizeof(float)*paramCount);
-
- // set-up engine
- options.processMode = PROCESS_MODE_CONTINUOUS_RACK;
- options.forceStereo = true;
- options.preferPluginBridges = false;
- options.preferUiBridges = false;
- init("Carla");
-
- // Force thread start so we get some OSC usage
- // (liblo locks otherwise)
- //startCheckThread();
-
- // testing
- idZyn = addPlugin(PLUGIN_DSSI, "/usr/lib/dssi/sineshaper.so", nullptr, "ll-sineshaper");
- }
-
- ~CarlaEnginePlugin()
- {
- qDebug("CarlaEnginePlugin::~CarlaEnginePlugin()");
-
- removeAllPlugins();
- close();
- }
-
- // -------------------------------------
- // CarlaEngine virtual calls
-
- bool init(const char* const clientName)
- {
- qDebug("CarlaEnginePlugin::init(\"%s\")", clientName);
-
- bufferSize = d_bufferSize();
- sampleRate = d_sampleRate();
-
- name = clientName;
- name.toBasic();
-
- CarlaEngine::init(name);
- return true;
- }
-
- bool close()
- {
- qDebug("CarlaEnginePlugin::close()");
- CarlaEngine::close();
-
- return true;
- }
-
- bool isRunning() const
- {
- return true;
- }
-
- bool isOffline() const
- {
- return false;
- }
-
- CarlaEngineType type() const
- {
- return CarlaEngineTypeRtAudio;
- }
-
- CarlaEngineClient* addClient(CarlaPlugin* const)
- {
- return new CarlaEnginePluginClient(CarlaEngineTypeRtAudio, options.processMode);
- }
-
-protected:
- // ---------------------------------------------
- // DISTRHO Plugin Information
-
- const char* d_label()
- {
- return "Carla";
- }
-
- const char* d_maker()
- {
- return "falkTX";
- }
-
- const char* d_license()
- {
- return "GPL v2+";
- }
-
- uint32_t d_version()
- {
- return 0x0500;
- }
-
- long d_uniqueId()
- {
- return d_cconst('C', 'r', 'l', 'a');
- }
-
- // ---------------------------------------------
- // DISTRHO Plugin Init
-
- void d_initParameter(uint32_t index, DISTRHO::Parameter& parameter)
- {
- if (index >= paramCount)
- return;
-
- parameter.hints = DISTRHO::PARAMETER_IS_AUTOMABLE;
- parameter.ranges.def = 0.0f;
- parameter.ranges.min = 0.0f;
- parameter.ranges.max = 127.0f;
-
- if (index == paramVolume)
- parameter.ranges.def = 100.0f;
- else if (index == paramBalance)
- parameter.ranges.def = 63.5f;
- else if (index == paramPan)
- parameter.ranges.def = 63.5f;
-
- switch (paramMap[index])
- {
- case 0x01:
- parameter.name = "0x01 Modulation";
- break;
- case 0x02:
- parameter.name = "0x02 Breath";
- break;
- case 0x03:
- parameter.name = "0x03 (Undefined)";
- break;
- case 0x04:
- parameter.name = "0x04 Foot";
- break;
- case 0x05:
- parameter.name = "0x05 Portamento";
- break;
- case 0x07:
- parameter.name = "0x07 Volume";
- break;
- case 0x08:
- parameter.name = "0x08 Balance";
- break;
- case 0x09:
- parameter.name = "0x09 (Undefined)";
- break;
- case 0x0A:
- parameter.name = "0x0A Pan";
- break;
- case 0x0B:
- parameter.name = "0x0B Expression";
- break;
- case 0x0C:
- parameter.name = "0x0C FX Control 1";
- break;
- case 0x0D:
- parameter.name = "0x0D FX Control 2";
- break;
- case 0x0E:
- parameter.name = "0x0E (Undefined)";
- break;
- case 0x0F:
- parameter.name = "0x0F (Undefined)";
- break;
- case 0x10:
- parameter.name = "0x10 General Purpose 1";
- break;
- case 0x11:
- parameter.name = "0x11 General Purpose 2";
- break;
- case 0x12:
- parameter.name = "0x12 General Purpose 3";
- break;
- case 0x13:
- parameter.name = "0x13 General Purpose 4";
- break;
- case 0x14:
- parameter.name = "0x14 (Undefined)";
- break;
- case 0x15:
- parameter.name = "0x15 (Undefined)";
- break;
- case 0x16:
- parameter.name = "0x16 (Undefined)";
- break;
- case 0x17:
- parameter.name = "0x17 (Undefined)";
- break;
- case 0x18:
- parameter.name = "0x18 (Undefined)";
- break;
- case 0x19:
- parameter.name = "0x19 (Undefined)";
- break;
- case 0x1A:
- parameter.name = "0x1A (Undefined)";
- break;
- case 0x1B:
- parameter.name = "0x1B (Undefined)";
- break;
- case 0x1C:
- parameter.name = "0x1C (Undefined)";
- break;
- case 0x1D:
- parameter.name = "0x1D (Undefined)";
- break;
- case 0x1E:
- parameter.name = "0x1E (Undefined)";
- break;
- case 0x1F:
- parameter.name = "0x1F (Undefined)";
- break;
- case 0x46:
- parameter.name = "0x46 Control 1 [Variation]";
- break;
- case 0x47:
- parameter.name = "0x47 Control 2 [Timbre]";
- break;
- case 0x48:
- parameter.name = "0x48 Control 3 [Release]";
- break;
- case 0x49:
- parameter.name = "0x49 Control 4 [Attack]";
- break;
- case 0x4A:
- parameter.name = "0x4A Control 5 [Brightness]";
- break;
- case 0x4B:
- parameter.name = "0x4B Control 6 [Decay]";
- break;
- case 0x4C:
- parameter.name = "0x4C Control 7 [Vib Rate]";
- break;
- case 0x4D:
- parameter.name = "0x4D Control 8 [Vib Depth]";
- break;
- case 0x4E:
- parameter.name = "0x4E Control 9 [Vib Delay]";
- break;
- case 0x4F:
- parameter.name = "0x4F Control 10 [Undefined]";
- break;
- case 0x50:
- parameter.name = "0x50 General Purpose 5";
- break;
- case 0x51:
- parameter.name = "0x51 General Purpose 6";
- break;
- case 0x52:
- parameter.name = "0x52 General Purpose 7";
- break;
- case 0x53:
- parameter.name = "0x53 General Purpose 8";
- break;
- case 0x54:
- parameter.name = "0x54 Portamento Control";
- break;
- case 0x5B:
- parameter.name = "0x5B FX 1 Depth [Reverb]";
- break;
- case 0x5C:
- parameter.name = "0x5C FX 2 Depth [Tremolo]";
- break;
- case 0x5D:
- parameter.name = "0x5D FX 3 Depth [Chorus]";
- break;
- case 0x5E:
- parameter.name = "0x5E FX 4 Depth [Detune]";
- break;
- case 0x5F:
- parameter.name = "0x5F FX 5 Depth [Phaser]";
- break;
- }
- }
-
- void d_initProgramName(uint32_t index, d_string& programName)
- {
- programName = "Program #" + d_string(index);
- }
-
- void d_initStateKey(uint32_t index, d_string& stateKey)
- {
- Q_UNUSED(index);
- Q_UNUSED(stateKey);
- }
-
- // ---------------------------------------------
- // DISTRHO Plugin Internal data
-
- float d_parameterValue(uint32_t index)
- {
- if (index >= paramCount)
- return 0.0f;
-
- return paramBuffers[index];
- }
-
- void d_setParameterValue(uint32_t index, float value)
- {
- if (index >= paramCount)
- return;
-
- paramBuffers[index] = value;
- }
-
- void d_setProgram(uint32_t index)
- {
- if (index >= programCount)
- return;
- if (maxPluginNumber() == 0)
- return;
-
- if (CarlaPlugin* const plugin = getPlugin(0))
- {
- if (index > plugin->programCount())
- plugin->setProgram(index, true, true, false, true);
- }
- }
-
- void d_setState(const char* key, const char* value)
- {
- Q_UNUSED(key);
- Q_UNUSED(value);
- }
-
- // ---------------------------------------------
- // DISTRHO Plugin Process
-
- void d_activate()
- {
-//#if 0
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-
- if (plugin && plugin->enabled())
- plugin->setActive(true, true, false);
- }
-//#endif
-
- memcpy(prevParamBuffers, paramBuffers, sizeof(float)*paramCount);
- }
-
- void d_deactivate()
- {
-//#if 0
- for (unsigned short i=0, max=maxPluginNumber(); i < max; i++)
- {
- CarlaPlugin* const plugin = getPluginUnchecked(i);
-
- if (plugin && plugin->enabled())
- plugin->setActive(false, true, false);
- }
-//#endif
- }
-
- void d_run(float** inputs, float** outputs, uint32_t frames, uint32_t midiEventCount, const DISTRHO::MidiEvent* midiEvents)
- {
- if (maxPluginNumber() == 0)
- return;
-
- // create audio buffers
- float* inBuf[2] = { (float*)inputs[0], (float*)inputs[1] };
- float* outBuf[2] = { outputs[0], outputs[1] };
-
- // initialize control input
- memset(rackControlEventsIn, 0, sizeof(CarlaEngineControlEvent)*CarlaEngine::MAX_CONTROL_EVENTS);
- {
- uint32_t carlaEventIndex = 0;
-
- for (unsigned int i=0; i < paramCount; i++)
- {
- if (prevParamBuffers[i] == paramBuffers[i])
- continue;
-
- CarlaEngineControlEvent* const carlaEvent = &rackControlEventsIn[carlaEventIndex++];
-
- carlaEvent->type = CarlaEngineParameterChangeEvent;
- carlaEvent->parameter = paramMap[i];
- carlaEvent->value = paramBuffers[i]/127;
- }
- }
- memcpy(prevParamBuffers, paramBuffers, sizeof(float)*paramCount);
-
- // initialize midi input
- memset(rackMidiEventsIn, 0, sizeof(CarlaEngineMidiEvent)*CarlaEngine::MAX_MIDI_EVENTS);
- {
- const DISTRHO::MidiEvent* event;
-
- for (uint32_t i=0, j=0; j < midiEventCount; j++)
- {
- if (i == CarlaEngine::MAX_MIDI_EVENTS)
- break;
-
- event = &midiEvents[j];
-
- rackMidiEventsIn[i].time = event->frame;
- rackMidiEventsIn[i].size = 3;
- memcpy(rackMidiEventsIn[i].data, event->buffer, 3);
- i += 1;
- }
- }
-
- processRack(inBuf, outBuf, frames);
- }
-
- // ---------------------------------------------
- // Callbacks
-
- void d_bufferSizeChanged(uint32_t newBufferSize)
- {
- bufferSizeChanged(newBufferSize);
- }
-
- // ---------------------------------------------
-
-private:
- float paramBuffers[paramCount];
- float prevParamBuffers[paramCount];
-};
-
-CARLA_BACKEND_END_NAMESPACE
-
-// -------------------------------------------------
-
-START_NAMESPACE_DISTRHO
-
-Plugin* createPlugin()
-{
- return new CarlaBackend::CarlaEnginePlugin();
-}
-
-END_NAMESPACE_DISTRHO
-
-// -------------------------------------------------
-
-#include "DistrhoPluginMain.cpp"
-
-#endif // CARLA_ENGINE_PLUGIN
diff --git a/c++/carla-engine/rtaudio-4.0.11/Makefile.in b/c++/carla-engine/rtaudio-4.0.11/Makefile.in
deleted file mode 100644
index c2cdcb1..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/Makefile.in
+++ /dev/null
@@ -1,57 +0,0 @@
-### Do not edit -- Generated by 'configure --with-whatever' from Makefile.in
-### RtAudio library Makefile
-
-RM = /bin/rm
-LN = /bin/ln
-
-OBJECTS = RtAudio.o @objects@
-
-STATIC = librtaudio.a
-SHARED = @sharedlib@
-RELEASE = 4.0.11
-MAJOR = 4
-LIBRARIES = $(STATIC) $(SHARED)
-
-CC = @CXX@
-AR = @AR@
-RANLIB = @RANLIB@
-
-DEFS = @CPPFLAGS@
-CFLAGS = @CXXFLAGS@ -Iinclude -fPIC
-
-all : $(LIBRARIES)
-
-tests:
- cd tests && $(MAKE) all
-
-$(LIBRARIES): $(OBJECTS)
- $(AR) ruv $(STATIC) $(OBJECTS)
- ranlib $(STATIC)
- $(CC) -fPIC @libflags@ $(OBJECTS) @LIBS@
- $(LN) -s @sharedname@ $(SHARED)
-
-# $(CC) -shared $(OBJECTS) -o $(SHARED) @LIBS@
-
-%.o : %.cpp
- $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
-
-%.o : include/%.cpp
- $(CC) $(CFLAGS) $(DEFS) -c $(<) -o $@
-
-clean :
- $(RM) -f $(LIBRARIES) @sharedname@ $(SHARED)*
- $(RM) -f $(OBJECTS)
- $(RM) -f *~
- cd tests && $(MAKE) clean
-
-distclean:
- $(RM) -f $(LIBRARIES) @sharedname@ $(SHARED)*
- $(RM) -f $(OBJECTS)
- $(RM) -f *~
- $(RM) -rf config.log config.status autom4te.cache Makefile rtaudio-config
- cd tests && $(MAKE) distclean
-
-strip :
- strip $(LIBRARIES)
- ranlib $(LIBRARIES)
- cd tests && $(MAKE) strip
diff --git a/c++/carla-engine/rtaudio-4.0.11/RtAudio.cpp b/c++/carla-engine/rtaudio-4.0.11/RtAudio.cpp
deleted file mode 100644
index 11467d3..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/RtAudio.cpp
+++ /dev/null
@@ -1,8363 +0,0 @@
-/************************************************************************/
-/*! \class RtAudio
- \brief Realtime audio i/o C++ classes.
-
- RtAudio provides a common API (Application Programming Interface)
- for realtime audio input/output across Linux (native ALSA, Jack,
- and OSS), Macintosh OS X (CoreAudio and Jack), and Windows
- (DirectSound and ASIO) operating systems.
-
- RtAudio WWW site: http://www.music.mcgill.ca/~gary/rtaudio/
-
- RtAudio: realtime audio i/o C++ classes
- Copyright (c) 2001-2012 Gary P. Scavone
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- Any person wishing to distribute modifications to the Software is
- asked to send the modifications to the original developer so that
- they can be incorporated into the canonical version. This is,
- however, not a binding provision of this license.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
- ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-/************************************************************************/
-
-// RtAudio: Version 4.0.11
-
-#include "RtAudio.h"
-#include
-#include
-#include
-#include
-
-// Static variable definitions.
-const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
-const unsigned int RtApi::SAMPLE_RATES[] = {
- 4000, 5512, 8000, 9600, 11025, 16000, 22050,
- 32000, 44100, 48000, 88200, 96000, 176400, 192000
-};
-
-#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
- #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A)
- #define MUTEX_DESTROY(A) DeleteCriticalSection(A)
- #define MUTEX_LOCK(A) EnterCriticalSection(A)
- #define MUTEX_UNLOCK(A) LeaveCriticalSection(A)
-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
- // pthread API
- #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
- #define MUTEX_DESTROY(A) pthread_mutex_destroy(A)
- #define MUTEX_LOCK(A) pthread_mutex_lock(A)
- #define MUTEX_UNLOCK(A) pthread_mutex_unlock(A)
-#else
- #define MUTEX_INITIALIZE(A) abs(*A) // dummy definitions
- #define MUTEX_DESTROY(A) abs(*A) // dummy definitions
-#endif
-
-// *************************************************** //
-//
-// RtAudio definitions.
-//
-// *************************************************** //
-
-void RtAudio :: getCompiledApi( std::vector &apis ) throw()
-{
- apis.clear();
-
- // The order here will control the order of RtAudio's API search in
- // the constructor.
-#if defined(__UNIX_JACK__)
- apis.push_back( UNIX_JACK );
-#endif
-#if defined(__LINUX_ALSA__)
- apis.push_back( LINUX_ALSA );
-#endif
-#if defined(__LINUX_PULSE__)
- apis.push_back( LINUX_PULSE );
-#endif
-#if defined(__LINUX_OSS__)
- apis.push_back( LINUX_OSS );
-#endif
-#if defined(__WINDOWS_ASIO__)
- apis.push_back( WINDOWS_ASIO );
-#endif
-#if defined(__WINDOWS_DS__)
- apis.push_back( WINDOWS_DS );
-#endif
-#if defined(__MACOSX_CORE__)
- apis.push_back( MACOSX_CORE );
-#endif
-#if defined(__RTAUDIO_DUMMY__)
- apis.push_back( RTAUDIO_DUMMY );
-#endif
-}
-
-void RtAudio :: openRtApi( RtAudio::Api api )
-{
- if ( rtapi_ )
- delete rtapi_;
- rtapi_ = 0;
-
-#if defined(__UNIX_JACK__)
- if ( api == UNIX_JACK )
- rtapi_ = new RtApiJack();
-#endif
-#if defined(__LINUX_ALSA__)
- if ( api == LINUX_ALSA )
- rtapi_ = new RtApiAlsa();
-#endif
-#if defined(__LINUX_PULSE__)
- if ( api == LINUX_PULSE )
- rtapi_ = new RtApiPulse();
-#endif
-#if defined(__LINUX_OSS__)
- if ( api == LINUX_OSS )
- rtapi_ = new RtApiOss();
-#endif
-#if defined(__WINDOWS_ASIO__)
- if ( api == WINDOWS_ASIO )
- rtapi_ = new RtApiAsio();
-#endif
-#if defined(__WINDOWS_DS__)
- if ( api == WINDOWS_DS )
- rtapi_ = new RtApiDs();
-#endif
-#if defined(__MACOSX_CORE__)
- if ( api == MACOSX_CORE )
- rtapi_ = new RtApiCore();
-#endif
-#if defined(__RTAUDIO_DUMMY__)
- if ( api == RTAUDIO_DUMMY )
- rtapi_ = new RtApiDummy();
-#endif
-}
-
-RtAudio :: RtAudio( RtAudio::Api api ) throw()
-{
- rtapi_ = 0;
-
- if ( api != UNSPECIFIED ) {
- // Attempt to open the specified API.
- openRtApi( api );
- if ( rtapi_ ) return;
-
- // No compiled support for specified API value. Issue a debug
- // warning and continue as if no API was specified.
- std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" << std::endl;
- }
-
- // Iterate through the compiled APIs and return as soon as we find
- // one with at least one device or we reach the end of the list.
- std::vector< RtAudio::Api > apis;
- getCompiledApi( apis );
- for ( unsigned int i=0; igetDeviceCount() ) break;
- }
-
- if ( rtapi_ ) return;
-
- // It should not be possible to get here because the preprocessor
- // definition __RTAUDIO_DUMMY__ is automatically defined if no
- // API-specific definitions are passed to the compiler. But just in
- // case something weird happens, we'll print out an error message.
- std::cerr << "\nRtAudio: no compiled API support found ... critical error!!\n\n";
-}
-
-RtAudio :: ~RtAudio() throw()
-{
- delete rtapi_;
-}
-
-void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
- RtAudio::StreamParameters *inputParameters,
- RtAudioFormat format, unsigned int sampleRate,
- unsigned int *bufferFrames,
- RtAudioCallback callback, void *userData,
- RtAudio::StreamOptions *options )
-{
- return rtapi_->openStream( outputParameters, inputParameters, format,
- sampleRate, bufferFrames, callback,
- userData, options );
-}
-
-// *************************************************** //
-//
-// Public RtApi definitions (see end of file for
-// private or protected utility functions).
-//
-// *************************************************** //
-
-RtApi :: RtApi()
-{
- stream_.state = STREAM_CLOSED;
- stream_.mode = UNINITIALIZED;
- stream_.apiHandle = 0;
- stream_.userBuffer[0] = 0;
- stream_.userBuffer[1] = 0;
- MUTEX_INITIALIZE( &stream_.mutex );
- showWarnings_ = true;
-}
-
-RtApi :: ~RtApi()
-{
- MUTEX_DESTROY( &stream_.mutex );
-}
-
-void RtApi :: openStream( RtAudio::StreamParameters *oParams,
- RtAudio::StreamParameters *iParams,
- RtAudioFormat format, unsigned int sampleRate,
- unsigned int *bufferFrames,
- RtAudioCallback callback, void *userData,
- RtAudio::StreamOptions *options )
-{
- if ( stream_.state != STREAM_CLOSED ) {
- errorText_ = "RtApi::openStream: a stream is already open!";
- error( RtError::INVALID_USE );
- }
-
- if ( oParams && oParams->nChannels < 1 ) {
- errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one.";
- error( RtError::INVALID_USE );
- }
-
- if ( iParams && iParams->nChannels < 1 ) {
- errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one.";
- error( RtError::INVALID_USE );
- }
-
- if ( oParams == NULL && iParams == NULL ) {
- errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!";
- error( RtError::INVALID_USE );
- }
-
- if ( formatBytes(format) == 0 ) {
- errorText_ = "RtApi::openStream: 'format' parameter value is undefined.";
- error( RtError::INVALID_USE );
- }
-
- unsigned int nDevices = getDeviceCount();
- unsigned int oChannels = 0;
- if ( oParams ) {
- oChannels = oParams->nChannels;
- if ( oParams->deviceId >= nDevices ) {
- errorText_ = "RtApi::openStream: output device parameter value is invalid.";
- error( RtError::INVALID_USE );
- }
- }
-
- unsigned int iChannels = 0;
- if ( iParams ) {
- iChannels = iParams->nChannels;
- if ( iParams->deviceId >= nDevices ) {
- errorText_ = "RtApi::openStream: input device parameter value is invalid.";
- error( RtError::INVALID_USE );
- }
- }
-
- clearStreamInfo();
- bool result;
-
- if ( oChannels > 0 ) {
-
- result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel,
- sampleRate, format, bufferFrames, options );
- if ( result == false ) error( RtError::SYSTEM_ERROR );
- }
-
- if ( iChannels > 0 ) {
-
- result = probeDeviceOpen( iParams->deviceId, INPUT, iChannels, iParams->firstChannel,
- sampleRate, format, bufferFrames, options );
- if ( result == false ) {
- if ( oChannels > 0 ) closeStream();
- error( RtError::SYSTEM_ERROR );
- }
- }
-
- stream_.callbackInfo.callback = (void *) callback;
- stream_.callbackInfo.userData = userData;
-
- if ( options ) options->numberOfBuffers = stream_.nBuffers;
- stream_.state = STREAM_STOPPED;
-}
-
-unsigned int RtApi :: getDefaultInputDevice( void )
-{
- // Should be implemented in subclasses if possible.
- return 0;
-}
-
-unsigned int RtApi :: getDefaultOutputDevice( void )
-{
- // Should be implemented in subclasses if possible.
- return 0;
-}
-
-void RtApi :: closeStream( void )
-{
- // MUST be implemented in subclasses!
- return;
-}
-
-bool RtApi :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options )
-{
- // MUST be implemented in subclasses!
- return FAILURE;
-
- // unused
- (void)device;
- (void)mode;
- (void)channels;
- (void)firstChannel;
- (void)sampleRate;
- (void)format;
- (void)bufferSize;
- (void)options;
-}
-
-void RtApi :: tickStreamTime( void )
-{
- // Subclasses that do not provide their own implementation of
- // getStreamTime should call this function once per buffer I/O to
- // provide basic stream time support.
-
- stream_.streamTime += ( stream_.bufferSize * 1.0 / stream_.sampleRate );
-
-#if defined( HAVE_GETTIMEOFDAY )
- gettimeofday( &stream_.lastTickTimestamp, NULL );
-#endif
-}
-
-long RtApi :: getStreamLatency( void )
-{
- verifyStream();
-
- long totalLatency = 0;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
- totalLatency = stream_.latency[0];
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
- totalLatency += stream_.latency[1];
-
- return totalLatency;
-}
-
-double RtApi :: getStreamTime( void )
-{
- verifyStream();
-
-#if defined( HAVE_GETTIMEOFDAY )
- // Return a very accurate estimate of the stream time by
- // adding in the elapsed time since the last tick.
- struct timeval then;
- struct timeval now;
-
- if ( stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0 )
- return stream_.streamTime;
-
- gettimeofday( &now, NULL );
- then = stream_.lastTickTimestamp;
- return stream_.streamTime +
- ((now.tv_sec + 0.000001 * now.tv_usec) -
- (then.tv_sec + 0.000001 * then.tv_usec));
-#else
- return stream_.streamTime;
-#endif
-}
-
-unsigned int RtApi :: getStreamSampleRate( void )
-{
- verifyStream();
-
- return stream_.sampleRate;
-}
-
-
-// *************************************************** //
-//
-// OS/API-specific methods.
-//
-// *************************************************** //
-
-#if defined(__MACOSX_CORE__)
-
-// The OS X CoreAudio API is designed to use a separate callback
-// procedure for each of its audio devices. A single RtAudio duplex
-// stream using two different devices is supported here, though it
-// cannot be guaranteed to always behave correctly because we cannot
-// synchronize these two callbacks.
-//
-// A property listener is installed for over/underrun information.
-// However, no functionality is currently provided to allow property
-// listeners to trigger user handlers because it is unclear what could
-// be done if a critical stream parameter (buffer size, sample rate,
-// device disconnect) notification arrived. The listeners entail
-// quite a bit of extra code and most likely, a user program wouldn't
-// be prepared for the result anyway. However, we do provide a flag
-// to the client callback function to inform of an over/underrun.
-
-// A structure to hold various information related to the CoreAudio API
-// implementation.
-struct CoreHandle {
- AudioDeviceID id[2]; // device ids
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
- AudioDeviceIOProcID procId[2];
-#endif
- UInt32 iStream[2]; // device stream index (or first if using multiple)
- UInt32 nStreams[2]; // number of streams to use
- bool xrun[2];
- char *deviceBuffer;
- pthread_cond_t condition;
- int drainCounter; // Tracks callback counts when draining
- bool internalDrain; // Indicates if stop is initiated from callback or not.
-
- CoreHandle()
- :deviceBuffer(0), drainCounter(0), internalDrain(false) { nStreams[0] = 1; nStreams[1] = 1; id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-ThreadHandle threadId;
-
-RtApiCore:: RtApiCore()
-{
-#if defined( AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER )
- // This is a largely undocumented but absolutely necessary
- // requirement starting with OS-X 10.6. If not called, queries and
- // updates to various audio device properties are not handled
- // correctly.
- CFRunLoopRef theRunLoop = NULL;
- AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- OSStatus result = AudioObjectSetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop);
- if ( result != noErr ) {
- errorText_ = "RtApiCore::RtApiCore: error setting run loop property!";
- error( RtError::WARNING );
- }
-#endif
-}
-
-RtApiCore :: ~RtApiCore()
-{
- // The subclass destructor gets called before the base class
- // destructor, so close an existing stream before deallocating
- // apiDeviceId memory.
- if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiCore :: getDeviceCount( void )
-{
- // Find out how many audio devices there are, if any.
- UInt32 dataSize;
- AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- OSStatus result = AudioObjectGetPropertyDataSize( kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize );
- if ( result != noErr ) {
- errorText_ = "RtApiCore::getDeviceCount: OS-X error getting device info!";
- error( RtError::WARNING );
- return 0;
- }
-
- return dataSize / sizeof( AudioDeviceID );
-}
-
-unsigned int RtApiCore :: getDefaultInputDevice( void )
-{
- unsigned int nDevices = getDeviceCount();
- if ( nDevices <= 1 ) return 0;
-
- AudioDeviceID id;
- UInt32 dataSize = sizeof( AudioDeviceID );
- AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id );
- if ( result != noErr ) {
- errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device.";
- error( RtError::WARNING );
- return 0;
- }
-
- dataSize *= nDevices;
- AudioDeviceID deviceList[ nDevices ];
- property.mSelector = kAudioHardwarePropertyDevices;
- result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList );
- if ( result != noErr ) {
- errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device IDs.";
- error( RtError::WARNING );
- return 0;
- }
-
- for ( unsigned int i=0; i= nDevices ) {
- errorText_ = "RtApiCore::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- AudioDeviceID deviceList[ nDevices ];
- UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
- AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
- 0, NULL, &dataSize, (void *) &deviceList );
- if ( result != noErr ) {
- errorText_ = "RtApiCore::getDeviceInfo: OS-X system error getting device IDs.";
- error( RtError::WARNING );
- return info;
- }
-
- AudioDeviceID id = deviceList[ device ];
-
- // Get the device name.
- info.name.erase();
- CFStringRef cfname;
- dataSize = sizeof( CFStringRef );
- property.mSelector = kAudioObjectPropertyManufacturer;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device manufacturer.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- //const char *mname = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
- int length = CFStringGetLength(cfname);
- char *mname = (char *)malloc(length * 3 + 1);
- CFStringGetCString(cfname, mname, length * 3 + 1, CFStringGetSystemEncoding());
- info.name.append( (const char *)mname, strlen(mname) );
- info.name.append( ": " );
- CFRelease( cfname );
- free(mname);
-
- property.mSelector = kAudioObjectPropertyName;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device name.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- //const char *name = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() );
- length = CFStringGetLength(cfname);
- char *name = (char *)malloc(length * 3 + 1);
- CFStringGetCString(cfname, name, length * 3 + 1, CFStringGetSystemEncoding());
- info.name.append( (const char *)name, strlen(name) );
- CFRelease( cfname );
- free(name);
-
- // Get the output stream "configuration".
- AudioBufferList *bufferList = nil;
- property.mSelector = kAudioDevicePropertyStreamConfiguration;
- property.mScope = kAudioDevicePropertyScopeOutput;
- // property.mElement = kAudioObjectPropertyElementWildcard;
- dataSize = 0;
- result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
- if ( result != noErr || dataSize == 0 ) {
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration info for device (" << device << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Allocate the AudioBufferList.
- bufferList = (AudioBufferList *) malloc( dataSize );
- if ( bufferList == NULL ) {
- errorText_ = "RtApiCore::getDeviceInfo: memory error allocating output AudioBufferList.";
- error( RtError::WARNING );
- return info;
- }
-
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
- if ( result != noErr || dataSize == 0 ) {
- free( bufferList );
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration for device (" << device << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Get output channel information.
- unsigned int i, nStreams = bufferList->mNumberBuffers;
- for ( i=0; imBuffers[i].mNumberChannels;
- free( bufferList );
-
- // Get the input stream "configuration".
- property.mScope = kAudioDevicePropertyScopeInput;
- result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
- if ( result != noErr || dataSize == 0 ) {
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration info for device (" << device << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Allocate the AudioBufferList.
- bufferList = (AudioBufferList *) malloc( dataSize );
- if ( bufferList == NULL ) {
- errorText_ = "RtApiCore::getDeviceInfo: memory error allocating input AudioBufferList.";
- error( RtError::WARNING );
- return info;
- }
-
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
- if (result != noErr || dataSize == 0) {
- free( bufferList );
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration for device (" << device << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Get input channel information.
- nStreams = bufferList->mNumberBuffers;
- for ( i=0; imBuffers[i].mNumberChannels;
- free( bufferList );
-
- // If device opens for both playback and capture, we determine the channels.
- if ( info.outputChannels > 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
- // Probe the device sample rates.
- bool isInput = false;
- if ( info.outputChannels == 0 ) isInput = true;
-
- // Determine the supported sample rates.
- property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
- if ( isInput == false ) property.mScope = kAudioDevicePropertyScopeOutput;
- result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
- if ( result != kAudioHardwareNoError || dataSize == 0 ) {
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rate info.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- UInt32 nRanges = dataSize / sizeof( AudioValueRange );
- AudioValueRange rangeList[ nRanges ];
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &rangeList );
- if ( result != kAudioHardwareNoError ) {
- errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rates.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- Float64 minimumRate = 100000000.0, maximumRate = 0.0;
- for ( UInt32 i=0; i maximumRate ) maximumRate = rangeList[i].mMaximum;
- }
-
- info.sampleRates.clear();
- for ( unsigned int k=0; k= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
- info.sampleRates.push_back( SAMPLE_RATES[k] );
- }
-
- if ( info.sampleRates.size() == 0 ) {
- errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // CoreAudio always uses 32-bit floating point data for PCM streams.
- // Thus, any other "physical" formats supported by the device are of
- // no interest to the client.
- info.nativeFormats = RTAUDIO_FLOAT32;
-
- if ( info.outputChannels > 0 )
- if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
- if ( info.inputChannels > 0 )
- if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
-
- info.probed = true;
- return info;
-}
-
-OSStatus callbackHandler( AudioDeviceID inDevice,
- const AudioTimeStamp* inNow,
- const AudioBufferList* inInputData,
- const AudioTimeStamp* inInputTime,
- AudioBufferList* outOutputData,
- const AudioTimeStamp* inOutputTime,
- void* infoPointer )
-{
- CallbackInfo *info = (CallbackInfo *) infoPointer;
-
- RtApiCore *object = (RtApiCore *) info->object;
- if ( object->callbackEvent( inDevice, inInputData, outOutputData ) == false )
- return kAudioHardwareUnspecifiedError;
- else
- return kAudioHardwareNoError;
-}
-
-OSStatus xrunListener( AudioObjectID inDevice,
- UInt32 nAddresses,
- const AudioObjectPropertyAddress properties[],
- void* handlePointer )
-{
- CoreHandle *handle = (CoreHandle *) handlePointer;
- for ( UInt32 i=0; ixrun[1] = true;
- else
- handle->xrun[0] = true;
- }
- }
-
- return kAudioHardwareNoError;
-}
-
-OSStatus rateListener( AudioObjectID inDevice,
- UInt32 nAddresses,
- const AudioObjectPropertyAddress properties[],
- void* ratePointer )
-{
-
- Float64 *rate = (Float64 *) ratePointer;
- UInt32 dataSize = sizeof( Float64 );
- AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- AudioObjectGetPropertyData( inDevice, &property, 0, NULL, &dataSize, rate );
- return kAudioHardwareNoError;
-}
-
-bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options )
-{
- // Get device ID
- unsigned int nDevices = getDeviceCount();
- if ( nDevices == 0 ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiCore::probeDeviceOpen: no devices found!";
- return FAILURE;
- }
-
- if ( device >= nDevices ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiCore::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
-
- AudioDeviceID deviceList[ nDevices ];
- UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices;
- AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
- OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property,
- 0, NULL, &dataSize, (void *) &deviceList );
- if ( result != noErr ) {
- errorText_ = "RtApiCore::probeDeviceOpen: OS-X system error getting device IDs.";
- return FAILURE;
- }
-
- AudioDeviceID id = deviceList[ device ];
-
- // Setup for stream mode.
- bool isInput = false;
- if ( mode == INPUT ) {
- isInput = true;
- property.mScope = kAudioDevicePropertyScopeInput;
- }
- else
- property.mScope = kAudioDevicePropertyScopeOutput;
-
- // Get the stream "configuration".
- AudioBufferList *bufferList = nil;
- dataSize = 0;
- property.mSelector = kAudioDevicePropertyStreamConfiguration;
- result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize );
- if ( result != noErr || dataSize == 0 ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration info for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Allocate the AudioBufferList.
- bufferList = (AudioBufferList *) malloc( dataSize );
- if ( bufferList == NULL ) {
- errorText_ = "RtApiCore::probeDeviceOpen: memory error allocating AudioBufferList.";
- return FAILURE;
- }
-
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList );
- if (result != noErr || dataSize == 0) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Search for one or more streams that contain the desired number of
- // channels. CoreAudio devices can have an arbitrary number of
- // streams and each stream can have an arbitrary number of channels.
- // For each stream, a single buffer of interleaved samples is
- // provided. RtAudio prefers the use of one stream of interleaved
- // data or multiple consecutive single-channel streams. However, we
- // now support multiple consecutive multi-channel streams of
- // interleaved data as well.
- UInt32 iStream, offsetCounter = firstChannel;
- UInt32 nStreams = bufferList->mNumberBuffers;
- bool monoMode = false;
- bool foundStream = false;
-
- // First check that the device supports the requested number of
- // channels.
- UInt32 deviceChannels = 0;
- for ( iStream=0; iStreammBuffers[iStream].mNumberChannels;
-
- if ( deviceChannels < ( channels + firstChannel ) ) {
- free( bufferList );
- errorStream_ << "RtApiCore::probeDeviceOpen: the device (" << device << ") does not support the requested channel count.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Look for a single stream meeting our needs.
- UInt32 firstStream, streamCount = 1, streamChannels = 0, channelOffset = 0;
- for ( iStream=0; iStreammBuffers[iStream].mNumberChannels;
- if ( streamChannels >= channels + offsetCounter ) {
- firstStream = iStream;
- channelOffset = offsetCounter;
- foundStream = true;
- break;
- }
- if ( streamChannels > offsetCounter ) break;
- offsetCounter -= streamChannels;
- }
-
- // If we didn't find a single stream above, then we should be able
- // to meet the channel specification with multiple streams.
- if ( foundStream == false ) {
- monoMode = true;
- offsetCounter = firstChannel;
- for ( iStream=0; iStreammBuffers[iStream].mNumberChannels;
- if ( streamChannels > offsetCounter ) break;
- offsetCounter -= streamChannels;
- }
-
- firstStream = iStream;
- channelOffset = offsetCounter;
- Int32 channelCounter = channels + offsetCounter - streamChannels;
-
- if ( streamChannels > 1 ) monoMode = false;
- while ( channelCounter > 0 ) {
- streamChannels = bufferList->mBuffers[++iStream].mNumberChannels;
- if ( streamChannels > 1 ) monoMode = false;
- channelCounter -= streamChannels;
- streamCount++;
- }
- }
-
- free( bufferList );
-
- // Determine the buffer size.
- AudioValueRange bufferRange;
- dataSize = sizeof( AudioValueRange );
- property.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &bufferRange );
-
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting buffer size range for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- if ( bufferRange.mMinimum > *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMinimum;
- else if ( bufferRange.mMaximum < *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMaximum;
- if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) *bufferSize = (unsigned long) bufferRange.mMinimum;
-
- // Set the buffer size. For multiple streams, I'm assuming we only
- // need to make this setting for the master channel.
- UInt32 theSize = (UInt32) *bufferSize;
- dataSize = sizeof( UInt32 );
- property.mSelector = kAudioDevicePropertyBufferFrameSize;
- result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &theSize );
-
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting the buffer size for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // If attempting to setup a duplex stream, the bufferSize parameter
- // MUST be the same in both directions!
- *bufferSize = theSize;
- if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- stream_.bufferSize = *bufferSize;
- stream_.nBuffers = 1;
-
- // Try to set "hog" mode ... it's not clear to me this is working.
- if ( options && options->flags & RTAUDIO_HOG_DEVICE ) {
- pid_t hog_pid;
- dataSize = sizeof( hog_pid );
- property.mSelector = kAudioDevicePropertyHogMode;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &hog_pid );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting 'hog' state!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- if ( hog_pid != getpid() ) {
- hog_pid = getpid();
- result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &hog_pid );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting 'hog' state!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
- }
-
- // Check and if necessary, change the sample rate for the device.
- Float64 nominalRate;
- dataSize = sizeof( Float64 );
- property.mSelector = kAudioDevicePropertyNominalSampleRate;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate );
-
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Only change the sample rate if off by more than 1 Hz.
- if ( fabs( nominalRate - (double)sampleRate ) > 1.0 ) {
-
- // Set a property listener for the sample rate change
- Float64 reportedRate = 0.0;
- AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
- result = AudioObjectAddPropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate property listener for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- nominalRate = (Float64) sampleRate;
- result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate );
-
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Now wait until the reported nominal rate is what we just set.
- UInt32 microCounter = 0;
- while ( reportedRate != nominalRate ) {
- microCounter += 5000;
- if ( microCounter > 5000000 ) break;
- usleep( 5000 );
- }
-
- // Remove the property listener.
- AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate );
-
- if ( microCounter > 5000000 ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: timeout waiting for sample rate update for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Now set the stream format for all streams. Also, check the
- // physical format of the device and change that if necessary.
- AudioStreamBasicDescription description;
- dataSize = sizeof( AudioStreamBasicDescription );
- property.mSelector = kAudioStreamPropertyVirtualFormat;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream format for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the sample rate and data format id. However, only make the
- // change if the sample rate is not within 1.0 of the desired
- // rate and the format is not linear pcm.
- bool updateFormat = false;
- if ( fabs( description.mSampleRate - (Float64)sampleRate ) > 1.0 ) {
- description.mSampleRate = (Float64) sampleRate;
- updateFormat = true;
- }
-
- if ( description.mFormatID != kAudioFormatLinearPCM ) {
- description.mFormatID = kAudioFormatLinearPCM;
- updateFormat = true;
- }
-
- if ( updateFormat ) {
- result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &description );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate or data format for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Now check the physical format.
- property.mSelector = kAudioStreamPropertyPhysicalFormat;
- result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream physical format for device (" << device << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- //std::cout << "Current physical stream format:" << std::endl;
- //std::cout << " mBitsPerChan = " << description.mBitsPerChannel << std::endl;
- //std::cout << " aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl;
- //std::cout << " bytesPerFrame = " << description.mBytesPerFrame << std::endl;
- //std::cout << " sample rate = " << description.mSampleRate << std::endl;
-
- if ( description.mFormatID != kAudioFormatLinearPCM || description.mBitsPerChannel < 16 ) {
- description.mFormatID = kAudioFormatLinearPCM;
- //description.mSampleRate = (Float64) sampleRate;
- AudioStreamBasicDescription testDescription = description;
- UInt32 formatFlags;
-
- // We'll try higher bit rates first and then work our way down.
- std::vector< std::pair > physicalFormats;
- formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger;
- physicalFormats.push_back( std::pair( 32, formatFlags ) );
- formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
- physicalFormats.push_back( std::pair( 32, formatFlags ) );
- physicalFormats.push_back( std::pair( 24, formatFlags ) ); // 24-bit packed
- formatFlags &= ~( kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh );
- physicalFormats.push_back( std::pair( 24.2, formatFlags ) ); // 24-bit in 4 bytes, aligned low
- formatFlags |= kAudioFormatFlagIsAlignedHigh;
- physicalFormats.push_back( std::pair( 24.4, formatFlags ) ); // 24-bit in 4 bytes, aligned high
- formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat;
- physicalFormats.push_back( std::pair( 16, formatFlags ) );
- physicalFormats.push_back( std::pair( 8, formatFlags ) );
-
- bool setPhysicalFormat = false;
- for( unsigned int i=0; iflags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
- else stream_.userInterleaved = true;
- stream_.deviceInterleaved[mode] = true;
- if ( monoMode == true ) stream_.deviceInterleaved[mode] = false;
-
- // Set flags for buffer conversion.
- stream_.doConvertBuffer[mode] = false;
- if ( stream_.userFormat != stream_.deviceFormat[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( streamCount == 1 ) {
- if ( stream_.nUserChannels[mode] > 1 &&
- stream_.userInterleaved != stream_.deviceInterleaved[mode] )
- stream_.doConvertBuffer[mode] = true;
- }
- else if ( monoMode && stream_.userInterleaved )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate our CoreHandle structure for the stream.
- CoreHandle *handle = 0;
- if ( stream_.apiHandle == 0 ) {
- try {
- handle = new CoreHandle;
- }
- catch ( std::bad_alloc& ) {
- errorText_ = "RtApiCore::probeDeviceOpen: error allocating CoreHandle memory.";
- goto error;
- }
-
- if ( pthread_cond_init( &handle->condition, NULL ) ) {
- errorText_ = "RtApiCore::probeDeviceOpen: error initializing pthread condition variable.";
- goto error;
- }
- stream_.apiHandle = (void *) handle;
- }
- else
- handle = (CoreHandle *) stream_.apiHandle;
- handle->iStream[mode] = firstStream;
- handle->nStreams[mode] = streamCount;
- handle->id[mode] = id;
-
- // Allocate necessary internal buffers.
- unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- // stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- stream_.userBuffer[mode] = (char *) malloc( bufferBytes * sizeof(char) );
- memset( stream_.userBuffer[mode], 0, bufferBytes * sizeof(char) );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiCore::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- // If possible, we will make use of the CoreAudio stream buffers as
- // "device buffers". However, we can't do this if using multiple
- // streams.
- if ( stream_.doConvertBuffer[mode] && handle->nStreams[mode] > 1 ) {
-
- bool makeBuffer = true;
- bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- stream_.sampleRate = sampleRate;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- stream_.callbackInfo.object = (void *) this;
-
- // Setup the buffer conversion information structure.
- if ( stream_.doConvertBuffer[mode] ) {
- if ( streamCount > 1 ) setConvertInfo( mode, 0 );
- else setConvertInfo( mode, channelOffset );
- }
-
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device )
- // Only one callback procedure per device.
- stream_.mode = DUPLEX;
- else {
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
- result = AudioDeviceCreateIOProcID( id, callbackHandler, (void *) &stream_.callbackInfo, &handle->procId[mode] );
-#else
- // deprecated in favor of AudioDeviceCreateIOProcID()
- result = AudioDeviceAddIOProc( id, callbackHandler, (void *) &stream_.callbackInfo );
-#endif
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::probeDeviceOpen: system error setting callback for device (" << device << ").";
- errorText_ = errorStream_.str();
- goto error;
- }
- if ( stream_.mode == OUTPUT && mode == INPUT )
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
- }
-
- // Setup the device property listener for over/underload.
- property.mSelector = kAudioDeviceProcessorOverload;
- result = AudioObjectAddPropertyListener( id, &property, xrunListener, (void *) handle );
-
- return SUCCESS;
-
- error:
- if ( handle ) {
- pthread_cond_destroy( &handle->condition );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiCore :: closeStream( void )
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiCore::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- if ( stream_.state == STREAM_RUNNING )
- AudioDeviceStop( handle->id[0], callbackHandler );
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
- AudioDeviceDestroyIOProcID( handle->id[0], handle->procId[0] );
-#else
- // deprecated in favor of AudioDeviceDestroyIOProcID()
- AudioDeviceRemoveIOProc( handle->id[0], callbackHandler );
-#endif
- }
-
- if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
- if ( stream_.state == STREAM_RUNNING )
- AudioDeviceStop( handle->id[1], callbackHandler );
-#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
- AudioDeviceDestroyIOProcID( handle->id[1], handle->procId[1] );
-#else
- // deprecated in favor of AudioDeviceDestroyIOProcID()
- AudioDeviceRemoveIOProc( handle->id[1], callbackHandler );
-#endif
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- // Destroy pthread condition variable.
- pthread_cond_destroy( &handle->condition );
- delete handle;
- stream_.apiHandle = 0;
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-void RtApiCore :: startStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiCore::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- OSStatus result = noErr;
- CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- result = AudioDeviceStart( handle->id[0], callbackHandler );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::startStream: system error (" << getErrorCode( result ) << ") starting callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT ||
- ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
-
- result = AudioDeviceStart( handle->id[1], callbackHandler );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::startStream: system error starting input callback procedure on device (" << stream_.device[1] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- handle->drainCounter = 0;
- handle->internalDrain = false;
- stream_.state = STREAM_RUNNING;
-
- unlock:
- if ( result == noErr ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiCore :: stopStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiCore::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- OSStatus result = noErr;
- CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- if ( handle->drainCounter == 0 ) {
- handle->drainCounter = 2;
- pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
- }
-
- result = AudioDeviceStop( handle->id[0], callbackHandler );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
-
- result = AudioDeviceStop( handle->id[1], callbackHandler );
- if ( result != noErr ) {
- errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping input callback procedure on device (" << stream_.device[1] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- stream_.state = STREAM_STOPPED;
-
- unlock:
- if ( result == noErr ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiCore :: abortStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiCore::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
- handle->drainCounter = 2;
-
- stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted. It is better to handle it this way because the
-// callbackEvent() function probably should return before the AudioDeviceStop()
-// function is called.
-extern "C" void *coreStopStream( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiCore *object = (RtApiCore *) info->object;
-
- object->stopStream();
- pthread_exit( NULL );
-}
-
-bool RtApiCore :: callbackEvent( AudioDeviceID deviceId,
- const AudioBufferList *inBufferList,
- const AudioBufferList *outBufferList )
-{
- if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return FAILURE;
- }
-
- CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
- CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
-
- // Check if we were draining the stream and signal is finished.
- if ( handle->drainCounter > 3 ) {
-
- stream_.state = STREAM_STOPPING;
- if ( handle->internalDrain == true )
- pthread_create( &threadId, NULL, coreStopStream, info );
- else // external call to stopStream()
- pthread_cond_signal( &handle->condition );
- return SUCCESS;
- }
-
- AudioDeviceID outputDevice = handle->id[0];
-
- // Invoke user callback to get fresh output data UNLESS we are
- // draining stream or duplex mode AND the input/output devices are
- // different AND this function is called for the input device.
- if ( handle->drainCounter == 0 && ( stream_.mode != DUPLEX || deviceId == outputDevice ) ) {
- RtAudioCallback callback = (RtAudioCallback) info->callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- handle->xrun[0] = false;
- }
- if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- handle->xrun[1] = false;
- }
-
- int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, info->userData );
- if ( cbReturnValue == 2 ) {
- stream_.state = STREAM_STOPPING;
- handle->drainCounter = 2;
- abortStream();
- return SUCCESS;
- }
- else if ( cbReturnValue == 1 ) {
- handle->drainCounter = 1;
- handle->internalDrain = true;
- }
- }
-
- if ( stream_.mode == OUTPUT || ( stream_.mode == DUPLEX && deviceId == outputDevice ) ) {
-
- if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
- if ( handle->nStreams[0] == 1 ) {
- memset( outBufferList->mBuffers[handle->iStream[0]].mData,
- 0,
- outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
- }
- else { // fill multiple streams with zeros
- for ( unsigned int i=0; inStreams[0]; i++ ) {
- memset( outBufferList->mBuffers[handle->iStream[0]+i].mData,
- 0,
- outBufferList->mBuffers[handle->iStream[0]+i].mDataByteSize );
- }
- }
- }
- else if ( handle->nStreams[0] == 1 ) {
- if ( stream_.doConvertBuffer[0] ) { // convert directly to CoreAudio stream buffer
- convertBuffer( (char *) outBufferList->mBuffers[handle->iStream[0]].mData,
- stream_.userBuffer[0], stream_.convertInfo[0] );
- }
- else { // copy from user buffer
- memcpy( outBufferList->mBuffers[handle->iStream[0]].mData,
- stream_.userBuffer[0],
- outBufferList->mBuffers[handle->iStream[0]].mDataByteSize );
- }
- }
- else { // fill multiple streams
- Float32 *inBuffer = (Float32 *) stream_.userBuffer[0];
- if ( stream_.doConvertBuffer[0] ) {
- convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
- inBuffer = (Float32 *) stream_.deviceBuffer;
- }
-
- if ( stream_.deviceInterleaved[0] == false ) { // mono mode
- UInt32 bufferBytes = outBufferList->mBuffers[handle->iStream[0]].mDataByteSize;
- for ( unsigned int i=0; imBuffers[handle->iStream[0]+i].mData,
- (void *)&inBuffer[i*stream_.bufferSize], bufferBytes );
- }
- }
- else { // fill multiple multi-channel streams with interleaved data
- UInt32 streamChannels, channelsLeft, inJump, outJump, inOffset;
- Float32 *out, *in;
-
- bool inInterleaved = ( stream_.userInterleaved ) ? true : false;
- UInt32 inChannels = stream_.nUserChannels[0];
- if ( stream_.doConvertBuffer[0] ) {
- inInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
- inChannels = stream_.nDeviceChannels[0];
- }
-
- if ( inInterleaved ) inOffset = 1;
- else inOffset = stream_.bufferSize;
-
- channelsLeft = inChannels;
- for ( unsigned int i=0; inStreams[0]; i++ ) {
- in = inBuffer;
- out = (Float32 *) outBufferList->mBuffers[handle->iStream[0]+i].mData;
- streamChannels = outBufferList->mBuffers[handle->iStream[0]+i].mNumberChannels;
-
- outJump = 0;
- // Account for possible channel offset in first stream
- if ( i == 0 && stream_.channelOffset[0] > 0 ) {
- streamChannels -= stream_.channelOffset[0];
- outJump = stream_.channelOffset[0];
- out += outJump;
- }
-
- // Account for possible unfilled channels at end of the last stream
- if ( streamChannels > channelsLeft ) {
- outJump = streamChannels - channelsLeft;
- streamChannels = channelsLeft;
- }
-
- // Determine input buffer offsets and skips
- if ( inInterleaved ) {
- inJump = inChannels;
- in += inChannels - channelsLeft;
- }
- else {
- inJump = 1;
- in += (inChannels - channelsLeft) * inOffset;
- }
-
- for ( unsigned int i=0; idrainCounter ) {
- handle->drainCounter++;
- goto unlock;
- }
- }
-
- AudioDeviceID inputDevice;
- inputDevice = handle->id[1];
- if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && deviceId == inputDevice ) ) {
-
- if ( handle->nStreams[1] == 1 ) {
- if ( stream_.doConvertBuffer[1] ) { // convert directly from CoreAudio stream buffer
- convertBuffer( stream_.userBuffer[1],
- (char *) inBufferList->mBuffers[handle->iStream[1]].mData,
- stream_.convertInfo[1] );
- }
- else { // copy to user buffer
- memcpy( stream_.userBuffer[1],
- inBufferList->mBuffers[handle->iStream[1]].mData,
- inBufferList->mBuffers[handle->iStream[1]].mDataByteSize );
- }
- }
- else { // read from multiple streams
- Float32 *outBuffer = (Float32 *) stream_.userBuffer[1];
- if ( stream_.doConvertBuffer[1] ) outBuffer = (Float32 *) stream_.deviceBuffer;
-
- if ( stream_.deviceInterleaved[1] == false ) { // mono mode
- UInt32 bufferBytes = inBufferList->mBuffers[handle->iStream[1]].mDataByteSize;
- for ( unsigned int i=0; imBuffers[handle->iStream[1]+i].mData, bufferBytes );
- }
- }
- else { // read from multiple multi-channel streams
- UInt32 streamChannels, channelsLeft, inJump, outJump, outOffset;
- Float32 *out, *in;
-
- bool outInterleaved = ( stream_.userInterleaved ) ? true : false;
- UInt32 outChannels = stream_.nUserChannels[1];
- if ( stream_.doConvertBuffer[1] ) {
- outInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode
- outChannels = stream_.nDeviceChannels[1];
- }
-
- if ( outInterleaved ) outOffset = 1;
- else outOffset = stream_.bufferSize;
-
- channelsLeft = outChannels;
- for ( unsigned int i=0; inStreams[1]; i++ ) {
- out = outBuffer;
- in = (Float32 *) inBufferList->mBuffers[handle->iStream[1]+i].mData;
- streamChannels = inBufferList->mBuffers[handle->iStream[1]+i].mNumberChannels;
-
- inJump = 0;
- // Account for possible channel offset in first stream
- if ( i == 0 && stream_.channelOffset[1] > 0 ) {
- streamChannels -= stream_.channelOffset[1];
- inJump = stream_.channelOffset[1];
- in += inJump;
- }
-
- // Account for possible unread channels at end of the last stream
- if ( streamChannels > channelsLeft ) {
- inJump = streamChannels - channelsLeft;
- streamChannels = channelsLeft;
- }
-
- // Determine output buffer offsets and skips
- if ( outInterleaved ) {
- outJump = outChannels;
- out += outChannels - channelsLeft;
- }
- else {
- outJump = 1;
- out += (outChannels - channelsLeft) * outOffset;
- }
-
- for ( unsigned int i=0; i
-#include
-#include
-
-// A structure to hold various information related to the Jack API
-// implementation.
-struct JackHandle {
- jack_client_t *client;
- jack_port_t **ports[2];
- std::string deviceName[2];
- bool xrun[2];
- pthread_cond_t condition;
- int drainCounter; // Tracks callback counts when draining
- bool internalDrain; // Indicates if stop is initiated from callback or not.
-
- JackHandle()
- :client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-ThreadHandle threadId;
-void jackSilentError( const char * ) {};
-
-RtApiJack :: RtApiJack()
-{
- // Nothing to do here.
-#if !defined(__RTAUDIO_DEBUG__)
- // Turn off Jack's internal error reporting.
- jack_set_error_function( &jackSilentError );
-#endif
-}
-
-RtApiJack :: ~RtApiJack()
-{
- if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiJack :: getDeviceCount( void )
-{
- // See if we can become a jack client.
- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
- jack_status_t *status = NULL;
- jack_client_t *client = jack_client_open( "RtApiJackCount", options, status );
- if ( client == 0 ) return 0;
-
- const char **ports;
- std::string port, previousPort;
- unsigned int nChannels = 0, nDevices = 0;
- ports = jack_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nChannels ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon + 1 );
- if ( port != previousPort ) {
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nChannels] );
- free( ports );
- }
-
- jack_client_close( client );
- return nDevices;
-}
-
-RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
-{
- RtAudio::DeviceInfo info;
- info.probed = false;
-
- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption
- jack_status_t *status = NULL;
- jack_client_t *client = jack_client_open( "RtApiJackInfo", options, status );
- if ( client == 0 ) {
- errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!";
- error( RtError::WARNING );
- return info;
- }
-
- const char **ports;
- std::string port, previousPort;
- unsigned int nPorts = 0, nDevices = 0;
- ports = jack_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nPorts ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon );
- if ( port != previousPort ) {
- if ( nDevices == device ) info.name = port;
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nPorts] );
- free( ports );
- }
-
- if ( device >= nDevices ) {
- jack_client_close( client );
- errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- // Get the current jack server sample rate.
- info.sampleRates.clear();
- info.sampleRates.push_back( jack_get_sample_rate( client ) );
-
- // Count the available ports containing the client name as device
- // channels. Jack "input ports" equal RtAudio output channels.
- unsigned int nChannels = 0;
- ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsInput );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- free( ports );
- info.outputChannels = nChannels;
- }
-
- // Jack "output ports" equal RtAudio input channels.
- nChannels = 0;
- ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- free( ports );
- info.inputChannels = nChannels;
- }
-
- if ( info.outputChannels == 0 && info.inputChannels == 0 ) {
- jack_client_close(client);
- errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!";
- error( RtError::WARNING );
- return info;
- }
-
- // If device opens for both playback and capture, we determine the channels.
- if ( info.outputChannels > 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
- // Jack always uses 32-bit floats.
- info.nativeFormats = RTAUDIO_FLOAT32;
-
- // Jack doesn't provide default devices so we'll use the first available one.
- if ( device == 0 && info.outputChannels > 0 )
- info.isDefaultOutput = true;
- if ( device == 0 && info.inputChannels > 0 )
- info.isDefaultInput = true;
-
- jack_client_close(client);
- info.probed = true;
- return info;
-}
-
-int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer )
-{
- CallbackInfo *info = (CallbackInfo *) infoPointer;
-
- RtApiJack *object = (RtApiJack *) info->object;
- if ( object->callbackEvent( (unsigned long) nframes ) == false ) return 1;
-
- return 0;
-}
-
-// This function will be called by a spawned thread when the Jack
-// server signals that it is shutting down. It is necessary to handle
-// it this way because the jackShutdown() function must return before
-// the jack_deactivate() function (in closeStream()) will return.
-extern "C" void *jackCloseStream( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiJack *object = (RtApiJack *) info->object;
-
- object->closeStream();
-
- pthread_exit( NULL );
-}
-void jackShutdown( void *infoPointer )
-{
- CallbackInfo *info = (CallbackInfo *) infoPointer;
- RtApiJack *object = (RtApiJack *) info->object;
-
- // Check current stream state. If stopped, then we'll assume this
- // was called as a result of a call to RtApiJack::stopStream (the
- // deactivation of a client handle causes this function to be called).
- // If not, we'll assume the Jack server is shutting down or some
- // other problem occurred and we should close the stream.
- if ( object->isStreamRunning() == false ) return;
-
- pthread_create( &threadId, NULL, jackCloseStream, info );
- std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" << std::endl;
-}
-
-int jackXrun( void *infoPointer )
-{
- JackHandle *handle = (JackHandle *) infoPointer;
-
- if ( handle->ports[0] ) handle->xrun[0] = true;
- if ( handle->ports[1] ) handle->xrun[1] = true;
-
- return 0;
-}
-
-bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options )
-{
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
-
- // Look for jack server and try to become a client (only do once per stream).
- jack_client_t *client = 0;
- if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) {
- jack_options_t jackoptions = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
- jack_status_t *status = NULL;
- if ( options && !options->streamName.empty() )
- client = jack_client_open( options->streamName.c_str(), jackoptions, status );
- else
- client = jack_client_open( "RtApiJack", jackoptions, status );
- if ( client == 0 ) {
- errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!";
- error( RtError::WARNING );
- return FAILURE;
- }
- }
- else {
- // The handle must have been created on an earlier pass.
- client = handle->client;
- }
-
- const char **ports;
- std::string port, previousPort, deviceName;
- unsigned int nPorts = 0, nDevices = 0;
- ports = jack_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nPorts ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon );
- if ( port != previousPort ) {
- if ( nDevices == device ) deviceName = port;
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nPorts] );
- free( ports );
- }
-
- if ( device >= nDevices ) {
- errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
-
- // Count the available ports containing the client name as device
- // channels. Jack "input ports" equal RtAudio output channels.
- unsigned int nChannels = 0;
- unsigned long flag = JackPortIsInput;
- if ( mode == INPUT ) flag = JackPortIsOutput;
- ports = jack_get_ports( client, deviceName.c_str(), NULL, flag );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- free( ports );
- }
-
- // Compare the jack ports for specified client to the requested number of channels.
- if ( nChannels < (channels + firstChannel) ) {
- errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Check the jack server sample rate.
- unsigned int jackRate = jack_get_sample_rate( client );
- if ( sampleRate != jackRate ) {
- jack_client_close( client );
- errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- stream_.sampleRate = jackRate;
-
- // Get the latency of the JACK port.
- ports = jack_get_ports( client, deviceName.c_str(), NULL, flag );
- if ( ports[ firstChannel ] )
- stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) );
- free( ports );
-
- // The jack server always uses 32-bit floating-point data.
- stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
- stream_.userFormat = format;
-
- if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
- else stream_.userInterleaved = true;
-
- // Jack always uses non-interleaved buffers.
- stream_.deviceInterleaved[mode] = false;
-
- // Jack always provides host byte-ordered data.
- stream_.doByteSwap[mode] = false;
-
- // Get the buffer size. The buffer size and number of buffers
- // (periods) is set when the jack server is started.
- stream_.bufferSize = (int) jack_get_buffer_size( client );
- *bufferSize = stream_.bufferSize;
-
- stream_.nDeviceChannels[mode] = channels;
- stream_.nUserChannels[mode] = channels;
-
- // Set flags for buffer conversion.
- stream_.doConvertBuffer[mode] = false;
- if ( stream_.userFormat != stream_.deviceFormat[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
- stream_.nUserChannels[mode] > 1 )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate our JackHandle structure for the stream.
- if ( handle == 0 ) {
- try {
- handle = new JackHandle;
- }
- catch ( std::bad_alloc& ) {
- errorText_ = "RtApiJack::probeDeviceOpen: error allocating JackHandle memory.";
- goto error;
- }
-
- if ( pthread_cond_init(&handle->condition, NULL) ) {
- errorText_ = "RtApiJack::probeDeviceOpen: error initializing pthread condition variable.";
- goto error;
- }
- stream_.apiHandle = (void *) handle;
- handle->client = client;
- }
- handle->deviceName[mode] = deviceName;
-
- // Allocate necessary internal buffers.
- unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- if ( stream_.doConvertBuffer[mode] ) {
-
- bool makeBuffer = true;
- if ( mode == OUTPUT )
- bufferBytes = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- else { // mode == INPUT
- bufferBytes = stream_.nDeviceChannels[1] * formatBytes( stream_.deviceFormat[1] );
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]);
- if ( bufferBytes < bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- // Allocate memory for the Jack ports (channels) identifiers.
- handle->ports[mode] = (jack_port_t **) malloc ( sizeof (jack_port_t *) * channels );
- if ( handle->ports[mode] == NULL ) {
- errorText_ = "RtApiJack::probeDeviceOpen: error allocating port memory.";
- goto error;
- }
-
- stream_.device[mode] = device;
- stream_.channelOffset[mode] = firstChannel;
- stream_.state = STREAM_STOPPED;
- stream_.callbackInfo.object = (void *) this;
-
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up the stream for output.
- stream_.mode = DUPLEX;
- else {
- stream_.mode = mode;
- jack_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo );
- jack_set_xrun_callback( handle->client, jackXrun, (void *) &handle );
- jack_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo );
- }
-
- // Register our ports.
- char label[64];
- if ( mode == OUTPUT ) {
- for ( unsigned int i=0; iports[0][i] = jack_port_register( handle->client, (const char *)label,
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
- }
- }
- else {
- for ( unsigned int i=0; iports[1][i] = jack_port_register( handle->client, (const char *)label,
- JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
- }
- }
-
- // Setup the buffer conversion information structure. We don't use
- // buffers to do channel offsets, so we override that parameter
- // here.
- if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
-
- return SUCCESS;
-
- error:
- if ( handle ) {
- pthread_cond_destroy( &handle->condition );
- jack_client_close( handle->client );
-
- if ( handle->ports[0] ) free( handle->ports[0] );
- if ( handle->ports[1] ) free( handle->ports[1] );
-
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiJack :: closeStream( void )
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiJack::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
- if ( handle ) {
-
- if ( stream_.state == STREAM_RUNNING )
- jack_deactivate( handle->client );
-
- jack_client_close( handle->client );
- }
-
- if ( handle ) {
- if ( handle->ports[0] ) free( handle->ports[0] );
- if ( handle->ports[1] ) free( handle->ports[1] );
- pthread_cond_destroy( &handle->condition );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-void RtApiJack :: startStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiJack::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
- int result = jack_activate( handle->client );
- if ( result ) {
- errorText_ = "RtApiJack::startStream(): unable to activate JACK client!";
- goto unlock;
- }
-
- const char **ports;
-
- // Get the list of available ports.
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- result = 1;
- ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput);
- if ( ports == NULL) {
- errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!";
- goto unlock;
- }
-
- // Now make the port connections. Since RtAudio wasn't designed to
- // allow the user to select particular channels of a device, we'll
- // just open the first "nChannels" ports with offset.
- for ( unsigned int i=0; iclient, jack_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] );
- if ( result ) {
- free( ports );
- errorText_ = "RtApiJack::startStream(): error connecting output ports!";
- goto unlock;
- }
- }
- free(ports);
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
- result = 1;
- ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput );
- if ( ports == NULL) {
- errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!";
- goto unlock;
- }
-
- // Now make the port connections. See note above.
- for ( unsigned int i=0; iclient, ports[ stream_.channelOffset[1] + i ], jack_port_name( handle->ports[1][i] ) );
- if ( result ) {
- free( ports );
- errorText_ = "RtApiJack::startStream(): error connecting input ports!";
- goto unlock;
- }
- }
- free(ports);
- }
-
- handle->drainCounter = 0;
- handle->internalDrain = false;
- stream_.state = STREAM_RUNNING;
-
- unlock:
- if ( result == 0 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiJack :: stopStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiJack::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- if ( handle->drainCounter == 0 ) {
- handle->drainCounter = 2;
- pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled
- }
- }
-
- jack_deactivate( handle->client );
- stream_.state = STREAM_STOPPED;
-}
-
-void RtApiJack :: abortStream( void )
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiJack::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
- handle->drainCounter = 2;
-
- stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted. It is necessary to handle it this way because the
-// callbackEvent() function must return before the jack_deactivate()
-// function will return.
-extern "C" void *jackStopStream( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiJack *object = (RtApiJack *) info->object;
-
- object->stopStream();
- pthread_exit( NULL );
-}
-
-bool RtApiJack :: callbackEvent( unsigned long nframes )
-{
- if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return FAILURE;
- }
- if ( stream_.bufferSize != nframes ) {
- errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!";
- error( RtError::WARNING );
- return FAILURE;
- }
-
- CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
- JackHandle *handle = (JackHandle *) stream_.apiHandle;
-
- // Check if we were draining the stream and signal is finished.
- if ( handle->drainCounter > 3 ) {
-
- stream_.state = STREAM_STOPPING;
- if ( handle->internalDrain == true )
- pthread_create( &threadId, NULL, jackStopStream, info );
- else
- pthread_cond_signal( &handle->condition );
- return SUCCESS;
- }
-
- // Invoke user callback first, to get fresh output data.
- if ( handle->drainCounter == 0 ) {
- RtAudioCallback callback = (RtAudioCallback) info->callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- handle->xrun[0] = false;
- }
- if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- handle->xrun[1] = false;
- }
- int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, info->userData );
- if ( cbReturnValue == 2 ) {
- stream_.state = STREAM_STOPPING;
- handle->drainCounter = 2;
- ThreadHandle id;
- pthread_create( &id, NULL, jackStopStream, info );
- return SUCCESS;
- }
- else if ( cbReturnValue == 1 ) {
- handle->drainCounter = 1;
- handle->internalDrain = true;
- }
- }
-
- jack_default_audio_sample_t *jackbuffer;
- unsigned long bufferBytes = nframes * sizeof( jack_default_audio_sample_t );
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
- for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes );
- memset( jackbuffer, 0, bufferBytes );
- }
-
- }
- else if ( stream_.doConvertBuffer[0] ) {
-
- convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
-
- for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes );
- memcpy( jackbuffer, &stream_.deviceBuffer[i*bufferBytes], bufferBytes );
- }
- }
- else { // no buffer conversion
- for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes );
- memcpy( jackbuffer, &stream_.userBuffer[0][i*bufferBytes], bufferBytes );
- }
- }
-
- if ( handle->drainCounter ) {
- handle->drainCounter++;
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- if ( stream_.doConvertBuffer[1] ) {
- for ( unsigned int i=0; iports[1][i], (jack_nframes_t) nframes );
- memcpy( &stream_.deviceBuffer[i*bufferBytes], jackbuffer, bufferBytes );
- }
- convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
- }
- else { // no buffer conversion
- for ( unsigned int i=0; iports[1][i], (jack_nframes_t) nframes );
- memcpy( &stream_.userBuffer[1][i*bufferBytes], jackbuffer, bufferBytes );
- }
- }
- }
-
- unlock:
- RtApi::tickStreamTime();
- return SUCCESS;
-}
- //******************** End of __UNIX_JACK__ *********************//
-#endif
-
-#if defined(__WINDOWS_ASIO__) // ASIO API on Windows
-
-// The ASIO API is designed around a callback scheme, so this
-// implementation is similar to that used for OS-X CoreAudio and Linux
-// Jack. The primary constraint with ASIO is that it only allows
-// access to a single driver at a time. Thus, it is not possible to
-// have more than one simultaneous RtAudio stream.
-//
-// This implementation also requires a number of external ASIO files
-// and a few global variables. The ASIO callback scheme does not
-// allow for the passing of user data, so we must create a global
-// pointer to our callbackInfo structure.
-//
-// On unix systems, we make use of a pthread condition variable.
-// Since there is no equivalent in Windows, I hacked something based
-// on information found in
-// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
-
-#include "asiosys.h"
-#include "asio.h"
-#include "iasiothiscallresolver.h"
-#include "asiodrivers.h"
-#include
-
-AsioDrivers drivers;
-ASIOCallbacks asioCallbacks;
-ASIODriverInfo driverInfo;
-CallbackInfo *asioCallbackInfo;
-bool asioXRun;
-
-struct AsioHandle {
- int drainCounter; // Tracks callback counts when draining
- bool internalDrain; // Indicates if stop is initiated from callback or not.
- ASIOBufferInfo *bufferInfos;
- HANDLE condition;
-
- AsioHandle()
- :drainCounter(0), internalDrain(false), bufferInfos(0) {}
-};
-
-// Function declarations (definitions at end of section)
-static const char* getAsioErrorString( ASIOError result );
-void sampleRateChanged( ASIOSampleRate sRate );
-long asioMessages( long selector, long value, void* message, double* opt );
-
-RtApiAsio :: RtApiAsio()
-{
- // ASIO cannot run on a multi-threaded appartment. You can call
- // CoInitialize beforehand, but it must be for appartment threading
- // (in which case, CoInitilialize will return S_FALSE here).
- coInitialized_ = false;
- HRESULT hr = CoInitialize( NULL );
- if ( FAILED(hr) ) {
- errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)";
- error( RtError::WARNING );
- }
- coInitialized_ = true;
-
- drivers.removeCurrentDriver();
- driverInfo.asioVersion = 2;
-
- // See note in DirectSound implementation about GetDesktopWindow().
- driverInfo.sysRef = GetForegroundWindow();
-}
-
-RtApiAsio :: ~RtApiAsio()
-{
- if ( stream_.state != STREAM_CLOSED ) closeStream();
- if ( coInitialized_ ) CoUninitialize();
-}
-
-unsigned int RtApiAsio :: getDeviceCount( void )
-{
- return (unsigned int) drivers.asioGetNumDev();
-}
-
-RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
-{
- RtAudio::DeviceInfo info;
- info.probed = false;
-
- // Get device ID
- unsigned int nDevices = getDeviceCount();
- if ( nDevices == 0 ) {
- errorText_ = "RtApiAsio::getDeviceInfo: no devices found!";
- error( RtError::INVALID_USE );
- }
-
- if ( device >= nDevices ) {
- errorText_ = "RtApiAsio::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- // If a stream is already open, we cannot probe other devices. Thus, use the saved results.
- if ( stream_.state != STREAM_CLOSED ) {
- if ( device >= devices_.size() ) {
- errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened.";
- error( RtError::WARNING );
- return info;
- }
- return devices_[ device ];
- }
-
- char driverName[32];
- ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 );
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::getDeviceInfo: unable to get driver name (" << getAsioErrorString( result ) << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- info.name = driverName;
-
- if ( !drivers.loadDriver( driverName ) ) {
- errorStream_ << "RtApiAsio::getDeviceInfo: unable to load driver (" << driverName << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- result = ASIOInit( &driverInfo );
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Determine the device channel information.
- long inputChannels, outputChannels;
- result = ASIOGetChannels( &inputChannels, &outputChannels );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- info.outputChannels = outputChannels;
- info.inputChannels = inputChannels;
- if ( info.outputChannels > 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
- // Determine the supported sample rates.
- info.sampleRates.clear();
- for ( unsigned int i=0; i 0 )
- if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true;
- if ( info.inputChannels > 0 )
- if ( getDefaultInputDevice() == device ) info.isDefaultInput = true;
-
- info.probed = true;
- drivers.removeCurrentDriver();
- return info;
-}
-
-void bufferSwitch( long index, ASIOBool processNow )
-{
- RtApiAsio *object = (RtApiAsio *) asioCallbackInfo->object;
- object->callbackEvent( index );
-}
-
-void RtApiAsio :: saveDeviceInfo( void )
-{
- devices_.clear();
-
- unsigned int nDevices = getDeviceCount();
- devices_.resize( nDevices );
- for ( unsigned int i=0; isaveDeviceInfo();
-
- if ( !drivers.loadDriver( driverName ) ) {
- errorStream_ << "RtApiAsio::probeDeviceOpen: unable to load driver (" << driverName << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- result = ASIOInit( &driverInfo );
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Check the device channel count.
- long inputChannels, outputChannels;
- result = ASIOGetChannels( &inputChannels, &outputChannels );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
- ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- stream_.nDeviceChannels[mode] = channels;
- stream_.nUserChannels[mode] = channels;
- stream_.channelOffset[mode] = firstChannel;
-
- // Verify the sample rate is supported.
- result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Get the current sample rate
- ASIOSampleRate currentRate;
- result = ASIOGetSampleRate( ¤tRate );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the sample rate only if necessary
- if ( currentRate != sampleRate ) {
- result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Determine the driver data type.
- ASIOChannelInfo channelInfo;
- channelInfo.channel = 0;
- if ( mode == OUTPUT ) channelInfo.isInput = false;
- else channelInfo.isInput = true;
- result = ASIOGetChannelInfo( &channelInfo );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Assuming WINDOWS host is always little-endian.
- stream_.doByteSwap[mode] = false;
- stream_.userFormat = format;
- stream_.deviceFormat[mode] = 0;
- if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- if ( channelInfo.type == ASIOSTInt16MSB ) stream_.doByteSwap[mode] = true;
- }
- else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- if ( channelInfo.type == ASIOSTInt32MSB ) stream_.doByteSwap[mode] = true;
- }
- else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB ) {
- stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
- if ( channelInfo.type == ASIOSTFloat32MSB ) stream_.doByteSwap[mode] = true;
- }
- else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) {
- stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
- if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true;
- }
-
- if ( stream_.deviceFormat[mode] == 0 ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the buffer size. For a duplex stream, this will end up
- // setting the buffer size based on the input constraints, which
- // should be ok.
- long minSize, maxSize, preferSize, granularity;
- result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
- if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- else if ( granularity == -1 ) {
- // Make sure bufferSize is a power of two.
- int log2_of_min_size = 0;
- int log2_of_max_size = 0;
-
- for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
- if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
- if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
- }
-
- long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
- int min_delta_num = log2_of_min_size;
-
- for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
- long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
- if (current_delta < min_delta) {
- min_delta = current_delta;
- min_delta_num = i;
- }
- }
-
- *bufferSize = ( (unsigned int)1 << min_delta_num );
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- }
- else if ( granularity != 0 ) {
- // Set to an even multiple of granularity, rounding up.
- *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
- }
-
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) {
- drivers.removeCurrentDriver();
- errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
- return FAILURE;
- }
-
- stream_.bufferSize = *bufferSize;
- stream_.nBuffers = 2;
-
- if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
- else stream_.userInterleaved = true;
-
- // ASIO always uses non-interleaved buffers.
- stream_.deviceInterleaved[mode] = false;
-
- // Allocate, if necessary, our AsioHandle structure for the stream.
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
- if ( handle == 0 ) {
- try {
- handle = new AsioHandle;
- }
- catch ( std::bad_alloc& ) {
- //if ( handle == NULL ) {
- drivers.removeCurrentDriver();
- errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
- return FAILURE;
- }
- handle->bufferInfos = 0;
-
- // Create a manual-reset event.
- handle->condition = CreateEvent( NULL, // no security
- TRUE, // manual-reset
- FALSE, // non-signaled initially
- NULL ); // unnamed
- stream_.apiHandle = (void *) handle;
- }
-
- // Create the ASIO internal buffers. Since RtAudio sets up input
- // and output separately, we'll have to dispose of previously
- // created output buffers for a duplex stream.
- long inputLatency, outputLatency;
- if ( mode == INPUT && stream_.mode == OUTPUT ) {
- ASIODisposeBuffers();
- if ( handle->bufferInfos ) free( handle->bufferInfos );
- }
-
- // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
- bool buffersAllocated = false;
- unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
- handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
- if ( handle->bufferInfos == NULL ) {
- errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
- errorText_ = errorStream_.str();
- goto error;
- }
-
- ASIOBufferInfo *infos;
- infos = handle->bufferInfos;
- for ( i=0; iisInput = ASIOFalse;
- infos->channelNum = i + stream_.channelOffset[0];
- infos->buffers[0] = infos->buffers[1] = 0;
- }
- for ( i=0; iisInput = ASIOTrue;
- infos->channelNum = i + stream_.channelOffset[1];
- infos->buffers[0] = infos->buffers[1] = 0;
- }
-
- // Set up the ASIO callback structure and create the ASIO data buffers.
- asioCallbacks.bufferSwitch = &bufferSwitch;
- asioCallbacks.sampleRateDidChange = &sampleRateChanged;
- asioCallbacks.asioMessage = &asioMessages;
- asioCallbacks.bufferSwitchTimeInfo = NULL;
- result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
- errorText_ = errorStream_.str();
- goto error;
- }
- buffersAllocated = true;
-
- // Set flags for buffer conversion.
- stream_.doConvertBuffer[mode] = false;
- if ( stream_.userFormat != stream_.deviceFormat[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
- stream_.nUserChannels[mode] > 1 )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate necessary internal buffers
- unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- if ( stream_.doConvertBuffer[mode] ) {
-
- bool makeBuffer = true;
- bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- stream_.sampleRate = sampleRate;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- asioCallbackInfo = &stream_.callbackInfo;
- stream_.callbackInfo.object = (void *) this;
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
-
- // Determine device latencies
- result = ASIOGetLatencies( &inputLatency, &outputLatency );
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING); // warn but don't fail
- }
- else {
- stream_.latency[0] = outputLatency;
- stream_.latency[1] = inputLatency;
- }
-
- // Setup the buffer conversion information structure. We don't use
- // buffers to do channel offsets, so we override that parameter
- // here.
- if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 );
-
- return SUCCESS;
-
- error:
- if ( buffersAllocated )
- ASIODisposeBuffers();
- drivers.removeCurrentDriver();
-
- if ( handle ) {
- CloseHandle( handle->condition );
- if ( handle->bufferInfos )
- free( handle->bufferInfos );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiAsio :: closeStream()
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiAsio::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- if ( stream_.state == STREAM_RUNNING ) {
- stream_.state = STREAM_STOPPED;
- ASIOStop();
- }
- ASIODisposeBuffers();
- drivers.removeCurrentDriver();
-
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
- if ( handle ) {
- CloseHandle( handle->condition );
- if ( handle->bufferInfos )
- free( handle->bufferInfos );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-bool stopThreadCalled = false;
-
-void RtApiAsio :: startStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiAsio::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
- ASIOError result = ASIOStart();
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::startStream: error (" << getAsioErrorString( result ) << ") starting device.";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- handle->drainCounter = 0;
- handle->internalDrain = false;
- ResetEvent( handle->condition );
- stream_.state = STREAM_RUNNING;
- asioXRun = false;
-
- unlock:
- stopThreadCalled = false;
-
- if ( result == ASE_OK ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiAsio :: stopStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiAsio::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- if ( handle->drainCounter == 0 ) {
- handle->drainCounter = 2;
- WaitForSingleObject( handle->condition, INFINITE ); // block until signaled
- }
- }
-
- stream_.state = STREAM_STOPPED;
-
- ASIOError result = ASIOStop();
- if ( result != ASE_OK ) {
- errorStream_ << "RtApiAsio::stopStream: error (" << getAsioErrorString( result ) << ") stopping device.";
- errorText_ = errorStream_.str();
- }
-
- if ( result == ASE_OK ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiAsio :: abortStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiAsio::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- // The following lines were commented-out because some behavior was
- // noted where the device buffers need to be zeroed to avoid
- // continuing sound, even when the device buffers are completely
- // disposed. So now, calling abort is the same as calling stop.
- // AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
- // handle->drainCounter = 2;
- stopStream();
-}
-
-// This function will be called by a spawned thread when the user
-// callback function signals that the stream should be stopped or
-// aborted. It is necessary to handle it this way because the
-// callbackEvent() function must return before the ASIOStop()
-// function will return.
-extern "C" unsigned __stdcall asioStopStream( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiAsio *object = (RtApiAsio *) info->object;
-
- object->stopStream();
- _endthreadex( 0 );
- return 0;
-}
-
-bool RtApiAsio :: callbackEvent( long bufferIndex )
-{
- if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiAsio::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return FAILURE;
- }
-
- CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
-
- // Check if we were draining the stream and signal if finished.
- if ( handle->drainCounter > 3 ) {
-
- stream_.state = STREAM_STOPPING;
- if ( handle->internalDrain == false )
- SetEvent( handle->condition );
- else { // spawn a thread to stop the stream
- unsigned threadId;
- stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
- &stream_.callbackInfo, 0, &threadId );
- }
- return SUCCESS;
- }
-
- // Invoke user callback to get fresh output data UNLESS we are
- // draining stream.
- if ( handle->drainCounter == 0 ) {
- RtAudioCallback callback = (RtAudioCallback) info->callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && asioXRun == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- asioXRun = false;
- }
- if ( stream_.mode != OUTPUT && asioXRun == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- asioXRun = false;
- }
- int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, info->userData );
- if ( cbReturnValue == 2 ) {
- stream_.state = STREAM_STOPPING;
- handle->drainCounter = 2;
- unsigned threadId;
- stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream,
- &stream_.callbackInfo, 0, &threadId );
- return SUCCESS;
- }
- else if ( cbReturnValue == 1 ) {
- handle->drainCounter = 1;
- handle->internalDrain = true;
- }
- }
-
- unsigned int nChannels, bufferBytes, i, j;
- nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] );
-
- if ( handle->drainCounter > 1 ) { // write zeros to the output stream
-
- for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue )
- memset( handle->bufferInfos[i].buffers[bufferIndex], 0, bufferBytes );
- }
-
- }
- else if ( stream_.doConvertBuffer[0] ) {
-
- convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] );
- if ( stream_.doByteSwap[0] )
- byteSwapBuffer( stream_.deviceBuffer,
- stream_.bufferSize * stream_.nDeviceChannels[0],
- stream_.deviceFormat[0] );
-
- for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue )
- memcpy( handle->bufferInfos[i].buffers[bufferIndex],
- &stream_.deviceBuffer[j++*bufferBytes], bufferBytes );
- }
-
- }
- else {
-
- if ( stream_.doByteSwap[0] )
- byteSwapBuffer( stream_.userBuffer[0],
- stream_.bufferSize * stream_.nUserChannels[0],
- stream_.userFormat );
-
- for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue )
- memcpy( handle->bufferInfos[i].buffers[bufferIndex],
- &stream_.userBuffer[0][bufferBytes*j++], bufferBytes );
- }
-
- }
-
- if ( handle->drainCounter ) {
- handle->drainCounter++;
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[1]);
-
- if (stream_.doConvertBuffer[1]) {
-
- // Always interleave ASIO input data.
- for ( i=0, j=0; ibufferInfos[i].isInput == ASIOTrue )
- memcpy( &stream_.deviceBuffer[j++*bufferBytes],
- handle->bufferInfos[i].buffers[bufferIndex],
- bufferBytes );
- }
-
- if ( stream_.doByteSwap[1] )
- byteSwapBuffer( stream_.deviceBuffer,
- stream_.bufferSize * stream_.nDeviceChannels[1],
- stream_.deviceFormat[1] );
- convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-
- }
- else {
- for ( i=0, j=0; ibufferInfos[i].isInput == ASIOTrue ) {
- memcpy( &stream_.userBuffer[1][bufferBytes*j++],
- handle->bufferInfos[i].buffers[bufferIndex],
- bufferBytes );
- }
- }
-
- if ( stream_.doByteSwap[1] )
- byteSwapBuffer( stream_.userBuffer[1],
- stream_.bufferSize * stream_.nUserChannels[1],
- stream_.userFormat );
- }
- }
-
- unlock:
- // The following call was suggested by Malte Clasen. While the API
- // documentation indicates it should not be required, some device
- // drivers apparently do not function correctly without it.
- ASIOOutputReady();
-
- RtApi::tickStreamTime();
- return SUCCESS;
-}
-
-void sampleRateChanged( ASIOSampleRate sRate )
-{
- // The ASIO documentation says that this usually only happens during
- // external sync. Audio processing is not stopped by the driver,
- // actual sample rate might not have even changed, maybe only the
- // sample rate status of an AES/EBU or S/PDIF digital input at the
- // audio device.
-
- RtApi *object = (RtApi *) asioCallbackInfo->object;
- try {
- object->stopStream();
- }
- catch ( RtError &exception ) {
- std::cerr << "\nRtApiAsio: sampleRateChanged() error (" << exception.getMessage() << ")!\n" << std::endl;
- return;
- }
-
- std::cerr << "\nRtApiAsio: driver reports sample rate changed to " << sRate << " ... stream stopped!!!\n" << std::endl;
-}
-
-long asioMessages( long selector, long value, void* message, double* opt )
-{
- long ret = 0;
-
- switch( selector ) {
- case kAsioSelectorSupported:
- if ( value == kAsioResetRequest
- || value == kAsioEngineVersion
- || value == kAsioResyncRequest
- || value == kAsioLatenciesChanged
- // The following three were added for ASIO 2.0, you don't
- // necessarily have to support them.
- || value == kAsioSupportsTimeInfo
- || value == kAsioSupportsTimeCode
- || value == kAsioSupportsInputMonitor)
- ret = 1L;
- break;
- case kAsioResetRequest:
- // Defer the task and perform the reset of the driver during the
- // next "safe" situation. You cannot reset the driver right now,
- // as this code is called from the driver. Reset the driver is
- // done by completely destruct is. I.e. ASIOStop(),
- // ASIODisposeBuffers(), Destruction Afterwards you initialize the
- // driver again.
- std::cerr << "\nRtApiAsio: driver reset requested!!!" << std::endl;
- ret = 1L;
- break;
- case kAsioResyncRequest:
- // This informs the application that the driver encountered some
- // non-fatal data loss. It is used for synchronization purposes
- // of different media. Added mainly to work around the Win16Mutex
- // problems in Windows 95/98 with the Windows Multimedia system,
- // which could lose data because the Mutex was held too long by
- // another thread. However a driver can issue it in other
- // situations, too.
- // std::cerr << "\nRtApiAsio: driver resync requested!!!" << std::endl;
- asioXRun = true;
- ret = 1L;
- break;
- case kAsioLatenciesChanged:
- // This will inform the host application that the drivers were
- // latencies changed. Beware, it this does not mean that the
- // buffer sizes have changed! You might need to update internal
- // delay data.
- std::cerr << "\nRtApiAsio: driver latency may have changed!!!" << std::endl;
- ret = 1L;
- break;
- case kAsioEngineVersion:
- // Return the supported ASIO version of the host application. If
- // a host application does not implement this selector, ASIO 1.0
- // is assumed by the driver.
- ret = 2L;
- break;
- case kAsioSupportsTimeInfo:
- // Informs the driver whether the
- // asioCallbacks.bufferSwitchTimeInfo() callback is supported.
- // For compatibility with ASIO 1.0 drivers the host application
- // should always support the "old" bufferSwitch method, too.
- ret = 0;
- break;
- case kAsioSupportsTimeCode:
- // Informs the driver whether application is interested in time
- // code info. If an application does not need to know about time
- // code, the driver has less work to do.
- ret = 0;
- break;
- }
- return ret;
-}
-
-static const char* getAsioErrorString( ASIOError result )
-{
- struct Messages
- {
- ASIOError value;
- const char*message;
- };
-
- static Messages m[] =
- {
- { ASE_NotPresent, "Hardware input or output is not present or available." },
- { ASE_HWMalfunction, "Hardware is malfunctioning." },
- { ASE_InvalidParameter, "Invalid input parameter." },
- { ASE_InvalidMode, "Invalid mode." },
- { ASE_SPNotAdvancing, "Sample position not advancing." },
- { ASE_NoClock, "Sample clock or rate cannot be determined or is not present." },
- { ASE_NoMemory, "Not enough memory to complete the request." }
- };
-
- for ( unsigned int i = 0; i < sizeof(m)/sizeof(m[0]); ++i )
- if ( m[i].value == result ) return m[i].message;
-
- return "Unknown error.";
-}
-//******************** End of __WINDOWS_ASIO__ *********************//
-#endif
-
-
-#if defined(__WINDOWS_DS__) // Windows DirectSound API
-
-// Modified by Robin Davies, October 2005
-// - Improvements to DirectX pointer chasing.
-// - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30.
-// - Auto-call CoInitialize for DSOUND and ASIO platforms.
-// Various revisions for RtAudio 4.0 by Gary Scavone, April 2007
-// Changed device query structure for RtAudio 4.0.7, January 2010
-
-#include
-#include
-#include
-
-#if defined(__MINGW32__)
- // missing from latest mingw winapi
-#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
-#define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */
-#define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */
-#define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */
-#endif
-
-#define MINIMUM_DEVICE_BUFFER_SIZE 32768
-
-#ifdef _MSC_VER // if Microsoft Visual C++
-#pragma comment( lib, "winmm.lib" ) // then, auto-link winmm.lib. Otherwise, it has to be added manually.
-#endif
-
-static inline DWORD dsPointerBetween( DWORD pointer, DWORD laterPointer, DWORD earlierPointer, DWORD bufferSize )
-{
- if ( pointer > bufferSize ) pointer -= bufferSize;
- if ( laterPointer < earlierPointer ) laterPointer += bufferSize;
- if ( pointer < earlierPointer ) pointer += bufferSize;
- return pointer >= earlierPointer && pointer < laterPointer;
-}
-
-// A structure to hold various information related to the DirectSound
-// API implementation.
-struct DsHandle {
- unsigned int drainCounter; // Tracks callback counts when draining
- bool internalDrain; // Indicates if stop is initiated from callback or not.
- void *id[2];
- void *buffer[2];
- bool xrun[2];
- UINT bufferPointer[2];
- DWORD dsBufferSize[2];
- DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by.
- HANDLE condition;
-
- DsHandle()
- :drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; }
-};
-
-// Declarations for utility functions, callbacks, and structures
-// specific to the DirectSound implementation.
-static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
- LPCTSTR description,
- LPCTSTR module,
- LPVOID lpContext );
-
-static const char* getErrorString( int code );
-
-extern "C" unsigned __stdcall callbackHandler( void *ptr );
-
-struct DsDevice {
- LPGUID id[2];
- bool validId[2];
- bool found;
- std::string name;
-
- DsDevice()
- : found(false) { validId[0] = false; validId[1] = false; }
-};
-
-std::vector< DsDevice > dsDevices;
-
-RtApiDs :: RtApiDs()
-{
- // Dsound will run both-threaded. If CoInitialize fails, then just
- // accept whatever the mainline chose for a threading model.
- coInitialized_ = false;
- HRESULT hr = CoInitialize( NULL );
- if ( !FAILED( hr ) ) coInitialized_ = true;
-}
-
-RtApiDs :: ~RtApiDs()
-{
- if ( coInitialized_ ) CoUninitialize(); // balanced call.
- if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-// The DirectSound default output is always the first device.
-unsigned int RtApiDs :: getDefaultOutputDevice( void )
-{
- return 0;
-}
-
-// The DirectSound default input is always the first input device,
-// which is the first capture device enumerated.
-unsigned int RtApiDs :: getDefaultInputDevice( void )
-{
- return 0;
-}
-
-unsigned int RtApiDs :: getDeviceCount( void )
-{
- // Set query flag for previously found devices to false, so that we
- // can check for any devices that have disappeared.
- for ( unsigned int i=0; i indices;
- for ( unsigned int i=0; i= dsDevices.size() ) {
- errorText_ = "RtApiDs::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- HRESULT result;
- if ( dsDevices[ device ].validId[0] == false ) goto probeInput;
-
- LPDIRECTSOUND output;
- DSCAPS outCaps;
- result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto probeInput;
- }
-
- outCaps.dwSize = sizeof( outCaps );
- result = output->GetCaps( &outCaps );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting capabilities!";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto probeInput;
- }
-
- // Get output channel information.
- info.outputChannels = ( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;
-
- // Get sample rate information.
- info.sampleRates.clear();
- for ( unsigned int k=0; k= (unsigned int) outCaps.dwMinSecondarySampleRate &&
- SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate )
- info.sampleRates.push_back( SAMPLE_RATES[k] );
- }
-
- // Get format information.
- if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) info.nativeFormats |= RTAUDIO_SINT8;
-
- output->Release();
-
- if ( getDefaultOutputDevice() == device )
- info.isDefaultOutput = true;
-
- if ( dsDevices[ device ].validId[1] == false ) {
- info.name = dsDevices[ device ].name;
- info.probed = true;
- return info;
- }
-
- probeInput:
-
- LPDIRECTSOUNDCAPTURE input;
- result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- DSCCAPS inCaps;
- inCaps.dwSize = sizeof( inCaps );
- result = input->GetCaps( &inCaps );
- if ( FAILED( result ) ) {
- input->Release();
- errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting object capabilities (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Get input channel information.
- info.inputChannels = inCaps.dwChannels;
-
- // Get sample rate and format information.
- std::vector rates;
- if ( inCaps.dwChannels >= 2 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) info.nativeFormats |= RTAUDIO_SINT8;
-
- if ( info.nativeFormats & RTAUDIO_SINT16 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) rates.push_back( 11025 );
- if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) rates.push_back( 22050 );
- if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) rates.push_back( 44100 );
- if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) rates.push_back( 96000 );
- }
- else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) rates.push_back( 11025 );
- if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) rates.push_back( 22050 );
- if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) rates.push_back( 44100 );
- if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) rates.push_back( 96000 );
- }
- }
- else if ( inCaps.dwChannels == 1 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) info.nativeFormats |= RTAUDIO_SINT16;
- if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) info.nativeFormats |= RTAUDIO_SINT8;
- if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) info.nativeFormats |= RTAUDIO_SINT8;
-
- if ( info.nativeFormats & RTAUDIO_SINT16 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) rates.push_back( 11025 );
- if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) rates.push_back( 22050 );
- if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) rates.push_back( 44100 );
- if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) rates.push_back( 96000 );
- }
- else if ( info.nativeFormats & RTAUDIO_SINT8 ) {
- if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) rates.push_back( 11025 );
- if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) rates.push_back( 22050 );
- if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) rates.push_back( 44100 );
- if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) rates.push_back( 96000 );
- }
- }
- else info.inputChannels = 0; // technically, this would be an error
-
- input->Release();
-
- if ( info.inputChannels == 0 ) return info;
-
- // Copy the supported rates to the info structure but avoid duplication.
- bool found;
- for ( unsigned int i=0; i 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
- if ( device == 0 ) info.isDefaultInput = true;
-
- // Copy name and return.
- info.name = dsDevices[ device ].name;
- info.probed = true;
- return info;
-}
-
-bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options )
-{
- if ( channels + firstChannel > 2 ) {
- errorText_ = "RtApiDs::probeDeviceOpen: DirectSound does not support more than 2 channels per device.";
- return FAILURE;
- }
-
- unsigned int nDevices = dsDevices.size();
- if ( nDevices == 0 ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiDs::probeDeviceOpen: no devices found!";
- return FAILURE;
- }
-
- if ( device >= nDevices ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiDs::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
-
- if ( mode == OUTPUT ) {
- if ( dsDevices[ device ].validId[0] == false ) {
- errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support output!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
- else { // mode == INPUT
- if ( dsDevices[ device ].validId[1] == false ) {
- errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support input!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // According to a note in PortAudio, using GetDesktopWindow()
- // instead of GetForegroundWindow() is supposed to avoid problems
- // that occur when the application's window is not the foreground
- // window. Also, if the application window closes before the
- // DirectSound buffer, DirectSound can crash. In the past, I had
- // problems when using GetDesktopWindow() but it seems fine now
- // (January 2010). I'll leave it commented here.
- // HWND hWnd = GetForegroundWindow();
- HWND hWnd = GetDesktopWindow();
-
- // Check the numberOfBuffers parameter and limit the lowest value to
- // two. This is a judgement call and a value of two is probably too
- // low for capture, but it should work for playback.
- int nBuffers = 0;
- if ( options ) nBuffers = options->numberOfBuffers;
- if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) nBuffers = 2;
- if ( nBuffers < 2 ) nBuffers = 3;
-
- // Check the lower range of the user-specified buffer size and set
- // (arbitrarily) to a lower bound of 32.
- if ( *bufferSize < 32 ) *bufferSize = 32;
-
- // Create the wave format structure. The data format setting will
- // be determined later.
- WAVEFORMATEX waveFormat;
- ZeroMemory( &waveFormat, sizeof(WAVEFORMATEX) );
- waveFormat.wFormatTag = WAVE_FORMAT_PCM;
- waveFormat.nChannels = channels + firstChannel;
- waveFormat.nSamplesPerSec = (unsigned long) sampleRate;
-
- // Determine the device buffer size. By default, we'll use the value
- // defined above (32K), but we will grow it to make allowances for
- // very large software buffer sizes.
- DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE;;
- DWORD dsPointerLeadTime = 0;
-
- void *ohandle = 0, *bhandle = 0;
- HRESULT result;
- if ( mode == OUTPUT ) {
-
- LPDIRECTSOUND output;
- result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- DSCAPS outCaps;
- outCaps.dwSize = sizeof( outCaps );
- result = output->GetCaps( &outCaps );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting capabilities (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Check channel information.
- if ( channels + firstChannel == 2 && !( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ) {
- errorStream_ << "RtApiDs::getDeviceInfo: the output device (" << dsDevices[ device ].name << ") does not support stereo playback.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Check format information. Use 16-bit format unless not
- // supported or user requests 8-bit.
- if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT &&
- !( format == RTAUDIO_SINT8 && outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) ) {
- waveFormat.wBitsPerSample = 16;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- }
- else {
- waveFormat.wBitsPerSample = 8;
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- }
- stream_.userFormat = format;
-
- // Update wave format structure and buffer information.
- waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
- waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
- dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
-
- // If the user wants an even bigger buffer, increase the device buffer size accordingly.
- while ( dsPointerLeadTime * 2U > dsBufferSize )
- dsBufferSize *= 2;
-
- // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes.
- // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE );
- // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes.
- result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting cooperative level (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Even though we will write to the secondary buffer, we need to
- // access the primary buffer to set the correct output format
- // (since the default is 8-bit, 22 kHz!). Setup the DS primary
- // buffer description.
- DSBUFFERDESC bufferDescription;
- ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
- bufferDescription.dwSize = sizeof( DSBUFFERDESC );
- bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
-
- // Obtain the primary buffer
- LPDIRECTSOUNDBUFFER buffer;
- result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") accessing primary buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the primary DS buffer sound format.
- result = buffer->SetFormat( &waveFormat );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting primary buffer format (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Setup the secondary DS buffer description.
- ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) );
- bufferDescription.dwSize = sizeof( DSBUFFERDESC );
- bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
- DSBCAPS_GLOBALFOCUS |
- DSBCAPS_GETCURRENTPOSITION2 |
- DSBCAPS_LOCHARDWARE ); // Force hardware mixing
- bufferDescription.dwBufferBytes = dsBufferSize;
- bufferDescription.lpwfxFormat = &waveFormat;
-
- // Try to create the secondary DS buffer. If that doesn't work,
- // try to use software mixing. Otherwise, there's a problem.
- result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
- if ( FAILED( result ) ) {
- bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS |
- DSBCAPS_GLOBALFOCUS |
- DSBCAPS_GETCURRENTPOSITION2 |
- DSBCAPS_LOCSOFTWARE ); // Force software mixing
- result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL );
- if ( FAILED( result ) ) {
- output->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating secondary buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Get the buffer size ... might be different from what we specified.
- DSBCAPS dsbcaps;
- dsbcaps.dwSize = sizeof( DSBCAPS );
- result = buffer->GetCaps( &dsbcaps );
- if ( FAILED( result ) ) {
- output->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- dsBufferSize = dsbcaps.dwBufferBytes;
-
- // Lock the DS buffer
- LPVOID audioPtr;
- DWORD dataLen;
- result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
- if ( FAILED( result ) ) {
- output->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Zero the DS buffer
- ZeroMemory( audioPtr, dataLen );
-
- // Unlock the DS buffer
- result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
- if ( FAILED( result ) ) {
- output->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- ohandle = (void *) output;
- bhandle = (void *) buffer;
- }
-
- if ( mode == INPUT ) {
-
- LPDIRECTSOUNDCAPTURE input;
- result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- DSCCAPS inCaps;
- inCaps.dwSize = sizeof( inCaps );
- result = input->GetCaps( &inCaps );
- if ( FAILED( result ) ) {
- input->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting input capabilities (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Check channel information.
- if ( inCaps.dwChannels < channels + firstChannel ) {
- errorText_ = "RtApiDs::getDeviceInfo: the input device does not support requested input channels.";
- return FAILURE;
- }
-
- // Check format information. Use 16-bit format unless user
- // requests 8-bit.
- DWORD deviceFormats;
- if ( channels + firstChannel == 2 ) {
- deviceFormats = WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08;
- if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
- waveFormat.wBitsPerSample = 8;
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- }
- else { // assume 16-bit is supported
- waveFormat.wBitsPerSample = 16;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- }
- }
- else { // channel == 1
- deviceFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08;
- if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) {
- waveFormat.wBitsPerSample = 8;
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- }
- else { // assume 16-bit is supported
- waveFormat.wBitsPerSample = 16;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- }
- }
- stream_.userFormat = format;
-
- // Update wave format structure and buffer information.
- waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8;
- waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
- dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels;
-
- // If the user wants an even bigger buffer, increase the device buffer size accordingly.
- while ( dsPointerLeadTime * 2U > dsBufferSize )
- dsBufferSize *= 2;
-
- // Setup the secondary DS buffer description.
- DSCBUFFERDESC bufferDescription;
- ZeroMemory( &bufferDescription, sizeof( DSCBUFFERDESC ) );
- bufferDescription.dwSize = sizeof( DSCBUFFERDESC );
- bufferDescription.dwFlags = 0;
- bufferDescription.dwReserved = 0;
- bufferDescription.dwBufferBytes = dsBufferSize;
- bufferDescription.lpwfxFormat = &waveFormat;
-
- // Create the capture buffer.
- LPDIRECTSOUNDCAPTUREBUFFER buffer;
- result = input->CreateCaptureBuffer( &bufferDescription, &buffer, NULL );
- if ( FAILED( result ) ) {
- input->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating input buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Get the buffer size ... might be different from what we specified.
- DSCBCAPS dscbcaps;
- dscbcaps.dwSize = sizeof( DSCBCAPS );
- result = buffer->GetCaps( &dscbcaps );
- if ( FAILED( result ) ) {
- input->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- dsBufferSize = dscbcaps.dwBufferBytes;
-
- // NOTE: We could have a problem here if this is a duplex stream
- // and the play and capture hardware buffer sizes are different
- // (I'm actually not sure if that is a problem or not).
- // Currently, we are not verifying that.
-
- // Lock the capture buffer
- LPVOID audioPtr;
- DWORD dataLen;
- result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 );
- if ( FAILED( result ) ) {
- input->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking input buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Zero the buffer
- ZeroMemory( audioPtr, dataLen );
-
- // Unlock the buffer
- result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
- if ( FAILED( result ) ) {
- input->Release();
- buffer->Release();
- errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking input buffer (" << dsDevices[ device ].name << ")!";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- ohandle = (void *) input;
- bhandle = (void *) buffer;
- }
-
- // Set various stream parameters
- DsHandle *handle = 0;
- stream_.nDeviceChannels[mode] = channels + firstChannel;
- stream_.nUserChannels[mode] = channels;
- stream_.bufferSize = *bufferSize;
- stream_.channelOffset[mode] = firstChannel;
- stream_.deviceInterleaved[mode] = true;
- if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false;
- else stream_.userInterleaved = true;
-
- // Set flag for buffer conversion
- stream_.doConvertBuffer[mode] = false;
- if (stream_.nUserChannels[mode] != stream_.nDeviceChannels[mode])
- stream_.doConvertBuffer[mode] = true;
- if (stream_.userFormat != stream_.deviceFormat[mode])
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
- stream_.nUserChannels[mode] > 1 )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate necessary internal buffers
- long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- if ( stream_.doConvertBuffer[mode] ) {
-
- bool makeBuffer = true;
- bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= (long) bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- // Allocate our DsHandle structures for the stream.
- if ( stream_.apiHandle == 0 ) {
- try {
- handle = new DsHandle;
- }
- catch ( std::bad_alloc& ) {
- errorText_ = "RtApiDs::probeDeviceOpen: error allocating AsioHandle memory.";
- goto error;
- }
-
- // Create a manual-reset event.
- handle->condition = CreateEvent( NULL, // no security
- TRUE, // manual-reset
- FALSE, // non-signaled initially
- NULL ); // unnamed
- stream_.apiHandle = (void *) handle;
- }
- else
- handle = (DsHandle *) stream_.apiHandle;
- handle->id[mode] = ohandle;
- handle->buffer[mode] = bhandle;
- handle->dsBufferSize[mode] = dsBufferSize;
- handle->dsPointerLeadTime[mode] = dsPointerLeadTime;
-
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
- stream_.nBuffers = nBuffers;
- stream_.sampleRate = sampleRate;
-
- // Setup the buffer conversion information structure.
- if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
- // Setup the callback thread.
- if ( stream_.callbackInfo.isRunning == false ) {
- unsigned threadId;
- stream_.callbackInfo.isRunning = true;
- stream_.callbackInfo.object = (void *) this;
- stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &callbackHandler,
- &stream_.callbackInfo, 0, &threadId );
- if ( stream_.callbackInfo.thread == 0 ) {
- errorText_ = "RtApiDs::probeDeviceOpen: error creating callback thread!";
- goto error;
- }
-
- // Boost DS thread priority
- SetThreadPriority( (HANDLE) stream_.callbackInfo.thread, THREAD_PRIORITY_HIGHEST );
- }
- return SUCCESS;
-
- error:
- if ( handle ) {
- if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
- LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
- LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- if ( buffer ) buffer->Release();
- object->Release();
- }
- if ( handle->buffer[1] ) {
- LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
- LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
- if ( buffer ) buffer->Release();
- object->Release();
- }
- CloseHandle( handle->condition );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiDs :: closeStream()
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiDs::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- // Stop the callback thread.
- stream_.callbackInfo.isRunning = false;
- WaitForSingleObject( (HANDLE) stream_.callbackInfo.thread, INFINITE );
- CloseHandle( (HANDLE) stream_.callbackInfo.thread );
-
- DsHandle *handle = (DsHandle *) stream_.apiHandle;
- if ( handle ) {
- if ( handle->buffer[0] ) { // the object pointer can be NULL and valid
- LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0];
- LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- if ( buffer ) {
- buffer->Stop();
- buffer->Release();
- }
- object->Release();
- }
- if ( handle->buffer[1] ) {
- LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1];
- LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
- if ( buffer ) {
- buffer->Stop();
- buffer->Release();
- }
- object->Release();
- }
- CloseHandle( handle->condition );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-void RtApiDs :: startStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiDs::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- DsHandle *handle = (DsHandle *) stream_.apiHandle;
-
- // Increase scheduler frequency on lesser windows (a side-effect of
- // increasing timer accuracy). On greater windows (Win2K or later),
- // this is already in effect.
- timeBeginPeriod( 1 );
-
- buffersRolling = false;
- duplexPrerollBytes = 0;
-
- if ( stream_.mode == DUPLEX ) {
- // 0.5 seconds of silence in DUPLEX mode while the devices spin up and synchronize.
- duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] );
- }
-
- HRESULT result = 0;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- result = buffer->Play( 0, 0, DSBPLAY_LOOPING );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting output buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
- result = buffer->Start( DSCBSTART_LOOPING );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting input buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- handle->drainCounter = 0;
- handle->internalDrain = false;
- ResetEvent( handle->condition );
- stream_.state = STREAM_RUNNING;
-
- unlock:
- if ( FAILED( result ) ) error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiDs :: stopStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiDs::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- HRESULT result = 0;
- LPVOID audioPtr;
- DWORD dataLen;
- DsHandle *handle = (DsHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- if ( handle->drainCounter == 0 ) {
- handle->drainCounter = 2;
- WaitForSingleObject( handle->condition, INFINITE ); // block until signaled
- }
-
- stream_.state = STREAM_STOPPED;
-
- // Stop the buffer and clear memory
- LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- result = buffer->Stop();
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping output buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // Lock the buffer and clear it so that if we start to play again,
- // we won't have old data playing.
- result = buffer->Lock( 0, handle->dsBufferSize[0], &audioPtr, &dataLen, NULL, NULL, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking output buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // Zero the DS buffer
- ZeroMemory( audioPtr, dataLen );
-
- // Unlock the DS buffer
- result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking output buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // If we start playing again, we must begin at beginning of buffer.
- handle->bufferPointer[0] = 0;
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
- LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
- audioPtr = NULL;
- dataLen = 0;
-
- stream_.state = STREAM_STOPPED;
-
- result = buffer->Stop();
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping input buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // Lock the buffer and clear it so that if we start to play again,
- // we won't have old data playing.
- result = buffer->Lock( 0, handle->dsBufferSize[1], &audioPtr, &dataLen, NULL, NULL, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking input buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // Zero the DS buffer
- ZeroMemory( audioPtr, dataLen );
-
- // Unlock the DS buffer
- result = buffer->Unlock( audioPtr, dataLen, NULL, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking input buffer!";
- errorText_ = errorStream_.str();
- goto unlock;
- }
-
- // If we start recording again, we must begin at beginning of buffer.
- handle->bufferPointer[1] = 0;
- }
-
- unlock:
- timeEndPeriod( 1 ); // revert to normal scheduler frequency on lesser windows.
- if ( FAILED( result ) ) error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiDs :: abortStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiDs::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- DsHandle *handle = (DsHandle *) stream_.apiHandle;
- handle->drainCounter = 2;
-
- stopStream();
-}
-
-void RtApiDs :: callbackEvent()
-{
- if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) {
- Sleep( 50 ); // sleep 50 milliseconds
- return;
- }
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiDs::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return;
- }
-
- CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
- DsHandle *handle = (DsHandle *) stream_.apiHandle;
-
- // Check if we were draining the stream and signal is finished.
- if ( handle->drainCounter > stream_.nBuffers + 2 ) {
-
- stream_.state = STREAM_STOPPING;
- if ( handle->internalDrain == false )
- SetEvent( handle->condition );
- else
- stopStream();
- return;
- }
-
- // Invoke user callback to get fresh output data UNLESS we are
- // draining stream.
- if ( handle->drainCounter == 0 ) {
- RtAudioCallback callback = (RtAudioCallback) info->callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- handle->xrun[0] = false;
- }
- if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- handle->xrun[1] = false;
- }
- int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, info->userData );
- if ( cbReturnValue == 2 ) {
- stream_.state = STREAM_STOPPING;
- handle->drainCounter = 2;
- abortStream();
- return;
- }
- else if ( cbReturnValue == 1 ) {
- handle->drainCounter = 1;
- handle->internalDrain = true;
- }
- }
-
- HRESULT result;
- DWORD currentWritePointer, safeWritePointer;
- DWORD currentReadPointer, safeReadPointer;
- UINT nextWritePointer;
-
- LPVOID buffer1 = NULL;
- LPVOID buffer2 = NULL;
- DWORD bufferSize1 = 0;
- DWORD bufferSize2 = 0;
-
- char *buffer;
- long bufferBytes;
-
- if ( buffersRolling == false ) {
- if ( stream_.mode == DUPLEX ) {
- //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
-
- // It takes a while for the devices to get rolling. As a result,
- // there's no guarantee that the capture and write device pointers
- // will move in lockstep. Wait here for both devices to start
- // rolling, and then set our buffer pointers accordingly.
- // e.g. Crystal Drivers: the capture buffer starts up 5700 to 9600
- // bytes later than the write buffer.
-
- // Stub: a serious risk of having a pre-emptive scheduling round
- // take place between the two GetCurrentPosition calls... but I'm
- // really not sure how to solve the problem. Temporarily boost to
- // Realtime priority, maybe; but I'm not sure what priority the
- // DirectSound service threads run at. We *should* be roughly
- // within a ms or so of correct.
-
- LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
-
- DWORD startSafeWritePointer, startSafeReadPointer;
-
- result = dsWriteBuffer->GetCurrentPosition( NULL, &startSafeWritePointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- result = dsCaptureBuffer->GetCurrentPosition( NULL, &startSafeReadPointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- while ( true ) {
- result = dsWriteBuffer->GetCurrentPosition( NULL, &safeWritePointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- result = dsCaptureBuffer->GetCurrentPosition( NULL, &safeReadPointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- if ( safeWritePointer != startSafeWritePointer && safeReadPointer != startSafeReadPointer ) break;
- Sleep( 1 );
- }
-
- //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] );
-
- handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
- if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
- handle->bufferPointer[1] = safeReadPointer;
- }
- else if ( stream_.mode == OUTPUT ) {
-
- // Set the proper nextWritePosition after initial startup.
- LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
- result = dsWriteBuffer->GetCurrentPosition( ¤tWritePointer, &safeWritePointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0];
- if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0];
- }
-
- buffersRolling = true;
- }
-
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0];
-
- if ( handle->drainCounter > 1 ) { // write zeros to the output stream
- bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
- bufferBytes *= formatBytes( stream_.userFormat );
- memset( stream_.userBuffer[0], 0, bufferBytes );
- }
-
- // Setup parameters and do buffer conversion if necessary.
- if ( stream_.doConvertBuffer[0] ) {
- buffer = stream_.deviceBuffer;
- convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
- bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[0];
- bufferBytes *= formatBytes( stream_.deviceFormat[0] );
- }
- else {
- buffer = stream_.userBuffer[0];
- bufferBytes = stream_.bufferSize * stream_.nUserChannels[0];
- bufferBytes *= formatBytes( stream_.userFormat );
- }
-
- // No byte swapping necessary in DirectSound implementation.
-
- // Ahhh ... windoze. 16-bit data is signed but 8-bit data is
- // unsigned. So, we need to convert our signed 8-bit data here to
- // unsigned.
- if ( stream_.deviceFormat[0] == RTAUDIO_SINT8 )
- for ( int i=0; idsBufferSize[0];
- nextWritePointer = handle->bufferPointer[0];
-
- DWORD endWrite, leadPointer;
- while ( true ) {
- // Find out where the read and "safe write" pointers are.
- result = dsBuffer->GetCurrentPosition( ¤tWritePointer, &safeWritePointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
-
- // We will copy our output buffer into the region between
- // safeWritePointer and leadPointer. If leadPointer is not
- // beyond the next endWrite position, wait until it is.
- leadPointer = safeWritePointer + handle->dsPointerLeadTime[0];
- //std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl;
- if ( leadPointer > dsBufferSize ) leadPointer -= dsBufferSize;
- if ( leadPointer < nextWritePointer ) leadPointer += dsBufferSize; // unwrap offset
- endWrite = nextWritePointer + bufferBytes;
-
- // Check whether the entire write region is behind the play pointer.
- if ( leadPointer >= endWrite ) break;
-
- // If we are here, then we must wait until the leadPointer advances
- // beyond the end of our next write region. We use the
- // Sleep() function to suspend operation until that happens.
- double millis = ( endWrite - leadPointer ) * 1000.0;
- millis /= ( formatBytes( stream_.deviceFormat[0]) * stream_.nDeviceChannels[0] * stream_.sampleRate);
- if ( millis < 1.0 ) millis = 1.0;
- Sleep( (DWORD) millis );
- }
-
- if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize )
- || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) {
- // We've strayed into the forbidden zone ... resync the read pointer.
- handle->xrun[0] = true;
- nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes;
- if ( nextWritePointer >= dsBufferSize ) nextWritePointer -= dsBufferSize;
- handle->bufferPointer[0] = nextWritePointer;
- endWrite = nextWritePointer + bufferBytes;
- }
-
- // Lock free space in the buffer
- result = dsBuffer->Lock( nextWritePointer, bufferBytes, &buffer1,
- &bufferSize1, &buffer2, &bufferSize2, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
-
- // Copy our buffer into the DS buffer
- CopyMemory( buffer1, buffer, bufferSize1 );
- if ( buffer2 != NULL ) CopyMemory( buffer2, buffer+bufferSize1, bufferSize2 );
-
- // Update our buffer offset and unlock sound buffer
- dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- nextWritePointer = ( nextWritePointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
- handle->bufferPointer[0] = nextWritePointer;
-
- if ( handle->drainCounter ) {
- handle->drainCounter++;
- goto unlock;
- }
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- // Setup parameters.
- if ( stream_.doConvertBuffer[1] ) {
- buffer = stream_.deviceBuffer;
- bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[1];
- bufferBytes *= formatBytes( stream_.deviceFormat[1] );
- }
- else {
- buffer = stream_.userBuffer[1];
- bufferBytes = stream_.bufferSize * stream_.nUserChannels[1];
- bufferBytes *= formatBytes( stream_.userFormat );
- }
-
- LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1];
- long nextReadPointer = handle->bufferPointer[1];
- DWORD dsBufferSize = handle->dsBufferSize[1];
-
- // Find out where the write and "safe read" pointers are.
- result = dsBuffer->GetCurrentPosition( ¤tReadPointer, &safeReadPointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
-
- if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
- DWORD endRead = nextReadPointer + bufferBytes;
-
- // Handling depends on whether we are INPUT or DUPLEX.
- // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode,
- // then a wait here will drag the write pointers into the forbidden zone.
- //
- // In DUPLEX mode, rather than wait, we will back off the read pointer until
- // it's in a safe position. This causes dropouts, but it seems to be the only
- // practical way to sync up the read and write pointers reliably, given the
- // the very complex relationship between phase and increment of the read and write
- // pointers.
- //
- // In order to minimize audible dropouts in DUPLEX mode, we will
- // provide a pre-roll period of 0.5 seconds in which we return
- // zeros from the read buffer while the pointers sync up.
-
- if ( stream_.mode == DUPLEX ) {
- if ( safeReadPointer < endRead ) {
- if ( duplexPrerollBytes <= 0 ) {
- // Pre-roll time over. Be more agressive.
- int adjustment = endRead-safeReadPointer;
-
- handle->xrun[1] = true;
- // Two cases:
- // - large adjustments: we've probably run out of CPU cycles, so just resync exactly,
- // and perform fine adjustments later.
- // - small adjustments: back off by twice as much.
- if ( adjustment >= 2*bufferBytes )
- nextReadPointer = safeReadPointer-2*bufferBytes;
- else
- nextReadPointer = safeReadPointer-bufferBytes-adjustment;
-
- if ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
-
- }
- else {
- // In pre=roll time. Just do it.
- nextReadPointer = safeReadPointer - bufferBytes;
- while ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize;
- }
- endRead = nextReadPointer + bufferBytes;
- }
- }
- else { // mode == INPUT
- while ( safeReadPointer < endRead && stream_.callbackInfo.isRunning ) {
- // See comments for playback.
- double millis = (endRead - safeReadPointer) * 1000.0;
- millis /= ( formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate);
- if ( millis < 1.0 ) millis = 1.0;
- Sleep( (DWORD) millis );
-
- // Wake up and find out where we are now.
- result = dsBuffer->GetCurrentPosition( ¤tReadPointer, &safeReadPointer );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
-
- if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset
- }
- }
-
- // Lock free space in the buffer
- result = dsBuffer->Lock( nextReadPointer, bufferBytes, &buffer1,
- &bufferSize1, &buffer2, &bufferSize2, 0 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
-
- if ( duplexPrerollBytes <= 0 ) {
- // Copy our buffer into the DS buffer
- CopyMemory( buffer, buffer1, bufferSize1 );
- if ( buffer2 != NULL ) CopyMemory( buffer+bufferSize1, buffer2, bufferSize2 );
- }
- else {
- memset( buffer, 0, bufferSize1 );
- if ( buffer2 != NULL ) memset( buffer + bufferSize1, 0, bufferSize2 );
- duplexPrerollBytes -= bufferSize1 + bufferSize2;
- }
-
- // Update our buffer offset and unlock sound buffer
- nextReadPointer = ( nextReadPointer + bufferSize1 + bufferSize2 ) % dsBufferSize;
- dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 );
- if ( FAILED( result ) ) {
- errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
- errorText_ = errorStream_.str();
- error( RtError::SYSTEM_ERROR );
- }
- handle->bufferPointer[1] = nextReadPointer;
-
- // No byte swapping necessary in DirectSound implementation.
-
- // If necessary, convert 8-bit data from unsigned to signed.
- if ( stream_.deviceFormat[1] == RTAUDIO_SINT8 )
- for ( int j=0; jobject;
- bool* isRunning = &info->isRunning;
-
- while ( *isRunning == true ) {
- object->callbackEvent();
- }
-
- _endthreadex( 0 );
- return 0;
-}
-
-#include "tchar.h"
-
-std::string convertTChar( LPCTSTR name )
-{
-#if defined( UNICODE ) || defined( _UNICODE )
- int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
- std::string s( length, 0 );
- length = WideCharToMultiByte(CP_UTF8, 0, name, wcslen(name), &s[0], length, NULL, NULL);
-#else
- std::string s( name );
-#endif
-
- return s;
-}
-
-static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
- LPCTSTR description,
- LPCTSTR module,
- LPVOID lpContext )
-{
- bool *isInput = (bool *) lpContext;
-
- HRESULT hr;
- bool validDevice = false;
- if ( *isInput == true ) {
- DSCCAPS caps;
- LPDIRECTSOUNDCAPTURE object;
-
- hr = DirectSoundCaptureCreate( lpguid, &object, NULL );
- if ( hr != DS_OK ) return TRUE;
-
- caps.dwSize = sizeof(caps);
- hr = object->GetCaps( &caps );
- if ( hr == DS_OK ) {
- if ( caps.dwChannels > 0 && caps.dwFormats > 0 )
- validDevice = true;
- }
- object->Release();
- }
- else {
- DSCAPS caps;
- LPDIRECTSOUND object;
- hr = DirectSoundCreate( lpguid, &object, NULL );
- if ( hr != DS_OK ) return TRUE;
-
- caps.dwSize = sizeof(caps);
- hr = object->GetCaps( &caps );
- if ( hr == DS_OK ) {
- if ( caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO )
- validDevice = true;
- }
- object->Release();
- }
-
- // If good device, then save its name and guid.
- std::string name = convertTChar( description );
- if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
- name = "Default Device";
- if ( validDevice ) {
- for ( unsigned int i=0; i
-#include
-
- // A structure to hold various information related to the ALSA API
- // implementation.
-struct AlsaHandle {
- snd_pcm_t *handles[2];
- bool synchronized;
- bool xrun[2];
- pthread_cond_t runnable_cv;
- bool runnable;
-
- AlsaHandle()
- :synchronized(false), runnable(false) { xrun[0] = false; xrun[1] = false; }
-};
-
-extern "C" void *alsaCallbackHandler( void * ptr );
-
-RtApiAlsa :: RtApiAlsa()
-{
- // Nothing to do here.
-}
-
-RtApiAlsa :: ~RtApiAlsa()
-{
- if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiAlsa :: getDeviceCount( void )
-{
- unsigned nDevices = 0;
- int result, subdevice, card;
- char name[64];
- snd_ctl_t *handle;
-
- // Count cards and devices
- card = -1;
- snd_card_next( &card );
- while ( card >= 0 ) {
- sprintf( name, "hw:%d", card );
- result = snd_ctl_open( &handle, name, 0 );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceCount: control open, card = " << card << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto nextcard;
- }
- subdevice = -1;
- while( 1 ) {
- result = snd_ctl_pcm_next_device( handle, &subdevice );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceCount: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- break;
- }
- if ( subdevice < 0 )
- break;
- nDevices++;
- }
- nextcard:
- snd_ctl_close( handle );
- snd_card_next( &card );
- }
-
- return nDevices;
-}
-
-RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
-{
- RtAudio::DeviceInfo info;
- info.probed = false;
-
- unsigned nDevices = 0;
- int result, subdevice, card;
- char name[64];
- snd_ctl_t *chandle;
-
- // Count cards and devices
- card = -1;
- snd_card_next( &card );
- while ( card >= 0 ) {
- sprintf( name, "hw:%d", card );
- result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceInfo: control open, card = " << card << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto nextcard;
- }
- subdevice = -1;
- while( 1 ) {
- result = snd_ctl_pcm_next_device( chandle, &subdevice );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceInfo: control next device, card = " << card << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- break;
- }
- if ( subdevice < 0 ) break;
- if ( nDevices == device ) {
- sprintf( name, "hw:%d,%d", card, subdevice );
- goto foundDevice;
- }
- nDevices++;
- }
- nextcard:
- snd_ctl_close( chandle );
- snd_card_next( &card );
- }
-
- if ( nDevices == 0 ) {
- errorText_ = "RtApiAlsa::getDeviceInfo: no devices found!";
- error( RtError::INVALID_USE );
- }
-
- if ( device >= nDevices ) {
- errorText_ = "RtApiAlsa::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- foundDevice:
-
- // If a stream is already open, we cannot probe the stream devices.
- // Thus, use the saved results.
- if ( stream_.state != STREAM_CLOSED &&
- ( stream_.device[0] == device || stream_.device[1] == device ) ) {
- snd_ctl_close( chandle );
- if ( device >= devices_.size() ) {
- errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened.";
- error( RtError::WARNING );
- return info;
- }
- return devices_[ device ];
- }
-
- int openMode = SND_PCM_ASYNC;
- snd_pcm_stream_t stream;
- snd_pcm_info_t *pcminfo;
- snd_pcm_info_alloca( &pcminfo );
- snd_pcm_t *phandle;
- snd_pcm_hw_params_t *params;
- snd_pcm_hw_params_alloca( ¶ms );
-
- // First try for playback
- stream = SND_PCM_STREAM_PLAYBACK;
- snd_pcm_info_set_device( pcminfo, subdevice );
- snd_pcm_info_set_subdevice( pcminfo, 0 );
- snd_pcm_info_set_stream( pcminfo, stream );
-
- result = snd_ctl_pcm_info( chandle, pcminfo );
- if ( result < 0 ) {
- // Device probably doesn't support playback.
- goto captureProbe;
- }
-
- result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto captureProbe;
- }
-
- // The device is open ... fill the parameter structure.
- result = snd_pcm_hw_params_any( phandle, params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto captureProbe;
- }
-
- // Get output channel information.
- unsigned int value;
- result = snd_pcm_hw_params_get_channels_max( params, &value );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- goto captureProbe;
- }
- info.outputChannels = value;
- snd_pcm_close( phandle );
-
- captureProbe:
- // Now try for capture
- stream = SND_PCM_STREAM_CAPTURE;
- snd_pcm_info_set_stream( pcminfo, stream );
-
- result = snd_ctl_pcm_info( chandle, pcminfo );
- snd_ctl_close( chandle );
- if ( result < 0 ) {
- // Device probably doesn't support capture.
- if ( info.outputChannels == 0 ) return info;
- goto probeParameters;
- }
-
- result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- if ( info.outputChannels == 0 ) return info;
- goto probeParameters;
- }
-
- // The device is open ... fill the parameter structure.
- result = snd_pcm_hw_params_any( phandle, params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- if ( info.outputChannels == 0 ) return info;
- goto probeParameters;
- }
-
- result = snd_pcm_hw_params_get_channels_max( params, &value );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- if ( info.outputChannels == 0 ) return info;
- goto probeParameters;
- }
- info.inputChannels = value;
- snd_pcm_close( phandle );
-
- // If device opens for both playback and capture, we determine the channels.
- if ( info.outputChannels > 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
-
- // ALSA doesn't provide default devices so we'll use the first available one.
- if ( device == 0 && info.outputChannels > 0 )
- info.isDefaultOutput = true;
- if ( device == 0 && info.inputChannels > 0 )
- info.isDefaultInput = true;
-
- probeParameters:
- // At this point, we just need to figure out the supported data
- // formats and sample rates. We'll proceed by opening the device in
- // the direction with the maximum number of channels, or playback if
- // they are equal. This might limit our sample rate options, but so
- // be it.
-
- if ( info.outputChannels >= info.inputChannels )
- stream = SND_PCM_STREAM_PLAYBACK;
- else
- stream = SND_PCM_STREAM_CAPTURE;
- snd_pcm_info_set_stream( pcminfo, stream );
-
- result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK);
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // The device is open ... fill the parameter structure.
- result = snd_pcm_hw_params_any( phandle, params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Test our discrete set of sample rate values.
- info.sampleRates.clear();
- for ( unsigned int i=0; i= 0 )
- sprintf( name, "hw:%s,%d", cardname, subdevice );
- info.name = name;
-
- // That's all ... close the device and return
- snd_pcm_close( phandle );
- info.probed = true;
- return info;
-}
-
-void RtApiAlsa :: saveDeviceInfo( void )
-{
- devices_.clear();
-
- unsigned int nDevices = getDeviceCount();
- devices_.resize( nDevices );
- for ( unsigned int i=0; iflags & RTAUDIO_ALSA_USE_DEFAULT )
- snprintf(name, sizeof(name), "%s", "default");
- else {
- // Count cards and devices
- card = -1;
- snd_card_next( &card );
- while ( card >= 0 ) {
- sprintf( name, "hw:%d", card );
- result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::probeDeviceOpen: control open, card = " << card << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- subdevice = -1;
- while( 1 ) {
- result = snd_ctl_pcm_next_device( chandle, &subdevice );
- if ( result < 0 ) break;
- if ( subdevice < 0 ) break;
- if ( nDevices == device ) {
- sprintf( name, "hw:%d,%d", card, subdevice );
- snd_ctl_close( chandle );
- goto foundDevice;
- }
- nDevices++;
- }
- snd_ctl_close( chandle );
- snd_card_next( &card );
- }
-
- if ( nDevices == 0 ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiAlsa::probeDeviceOpen: no devices found!";
- return FAILURE;
- }
-
- if ( device >= nDevices ) {
- // This should not happen because a check is made before this function is called.
- errorText_ = "RtApiAlsa::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
- }
-
- foundDevice:
-
- // The getDeviceInfo() function will not work for a device that is
- // already open. Thus, we'll probe the system before opening a
- // stream and save the results for use by getDeviceInfo().
- if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) // only do once
- this->saveDeviceInfo();
-
- snd_pcm_stream_t stream;
- if ( mode == OUTPUT )
- stream = SND_PCM_STREAM_PLAYBACK;
- else
- stream = SND_PCM_STREAM_CAPTURE;
-
- snd_pcm_t *phandle;
- int openMode = SND_PCM_ASYNC;
- result = snd_pcm_open( &phandle, name, stream, openMode );
- if ( result < 0 ) {
- if ( mode == OUTPUT )
- errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for output.";
- else
- errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for input.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Fill the parameter structure.
- snd_pcm_hw_params_t *hw_params;
- snd_pcm_hw_params_alloca( &hw_params );
- result = snd_pcm_hw_params_any( phandle, hw_params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
-#if defined(__RTAUDIO_DEBUG__)
- fprintf( stderr, "\nRtApiAlsa: dump hardware params just after device open:\n\n" );
- snd_pcm_hw_params_dump( hw_params, out );
-#endif
-
- // Set access ... check user preference.
- if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) {
- stream_.userInterleaved = false;
- result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
- if ( result < 0 ) {
- result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
- stream_.deviceInterleaved[mode] = true;
- }
- else
- stream_.deviceInterleaved[mode] = false;
- }
- else {
- stream_.userInterleaved = true;
- result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED );
- if ( result < 0 ) {
- result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED );
- stream_.deviceInterleaved[mode] = false;
- }
- else
- stream_.deviceInterleaved[mode] = true;
- }
-
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Determine how to set the device format.
- stream_.userFormat = format;
- snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN;
-
- if ( format == RTAUDIO_SINT8 )
- deviceFormat = SND_PCM_FORMAT_S8;
- else if ( format == RTAUDIO_SINT16 )
- deviceFormat = SND_PCM_FORMAT_S16;
- else if ( format == RTAUDIO_SINT24 )
- deviceFormat = SND_PCM_FORMAT_S24;
- else if ( format == RTAUDIO_SINT32 )
- deviceFormat = SND_PCM_FORMAT_S32;
- else if ( format == RTAUDIO_FLOAT32 )
- deviceFormat = SND_PCM_FORMAT_FLOAT;
- else if ( format == RTAUDIO_FLOAT64 )
- deviceFormat = SND_PCM_FORMAT_FLOAT64;
-
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) {
- stream_.deviceFormat[mode] = format;
- goto setFormat;
- }
-
- // The user requested format is not natively supported by the device.
- deviceFormat = SND_PCM_FORMAT_FLOAT64;
- if ( snd_pcm_hw_params_test_format( phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_FLOAT64;
- goto setFormat;
- }
-
- deviceFormat = SND_PCM_FORMAT_FLOAT;
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_FLOAT32;
- goto setFormat;
- }
-
- deviceFormat = SND_PCM_FORMAT_S32;
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- goto setFormat;
- }
-
- deviceFormat = SND_PCM_FORMAT_S24;
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT24;
- goto setFormat;
- }
-
- deviceFormat = SND_PCM_FORMAT_S16;
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- goto setFormat;
- }
-
- deviceFormat = SND_PCM_FORMAT_S8;
- if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) {
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- goto setFormat;
- }
-
- // If we get here, no supported format was found.
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio.";
- errorText_ = errorStream_.str();
- return FAILURE;
-
- setFormat:
- result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Determine whether byte-swaping is necessary.
- stream_.doByteSwap[mode] = false;
- if ( deviceFormat != SND_PCM_FORMAT_S8 ) {
- result = snd_pcm_format_cpu_endian( deviceFormat );
- if ( result == 0 )
- stream_.doByteSwap[mode] = true;
- else if (result < 0) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
-
- // Set the sample rate.
- result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Determine the number of channels for this device. We support a possible
- // minimum device channel number > than the value requested by the user.
- stream_.nUserChannels[mode] = channels;
- unsigned int value;
- result = snd_pcm_hw_params_get_channels_max( hw_params, &value );
- unsigned int deviceChannels = value;
- if ( result < 0 || deviceChannels < channels + firstChannel ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- result = snd_pcm_hw_params_get_channels_min( hw_params, &value );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- deviceChannels = value;
- if ( deviceChannels < channels + firstChannel ) deviceChannels = channels + firstChannel;
- stream_.nDeviceChannels[mode] = deviceChannels;
-
- // Set the device channels.
- result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the buffer (or period) size.
- int dir = 0;
- snd_pcm_uframes_t periodSize = *bufferSize;
- result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- *bufferSize = periodSize;
-
- // Set the buffer number, which in ALSA is referred to as the "period".
- unsigned int periods = 0;
- if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) periods = 2;
- if ( options && options->numberOfBuffers > 0 ) periods = options->numberOfBuffers;
- if ( periods < 2 ) periods = 4; // a fairly safe default value
- result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // If attempting to setup a duplex stream, the bufferSize parameter
- // MUST be the same in both directions!
- if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- stream_.bufferSize = *bufferSize;
-
- // Install the hardware configuration
- result = snd_pcm_hw_params( phandle, hw_params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
-#if defined(__RTAUDIO_DEBUG__)
- fprintf(stderr, "\nRtApiAlsa: dump hardware params after installation:\n\n");
- snd_pcm_hw_params_dump( hw_params, out );
-#endif
-
- // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns.
- snd_pcm_sw_params_t *sw_params = NULL;
- snd_pcm_sw_params_alloca( &sw_params );
- snd_pcm_sw_params_current( phandle, sw_params );
- snd_pcm_sw_params_set_start_threshold( phandle, sw_params, *bufferSize );
- snd_pcm_sw_params_set_stop_threshold( phandle, sw_params, ULONG_MAX );
- snd_pcm_sw_params_set_silence_threshold( phandle, sw_params, 0 );
-
- // The following two settings were suggested by Theo Veenker
- //snd_pcm_sw_params_set_avail_min( phandle, sw_params, *bufferSize );
- //snd_pcm_sw_params_set_xfer_align( phandle, sw_params, 1 );
-
- // here are two options for a fix
- //snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX );
- snd_pcm_uframes_t val;
- snd_pcm_sw_params_get_boundary( sw_params, &val );
- snd_pcm_sw_params_set_silence_size( phandle, sw_params, val );
-
- result = snd_pcm_sw_params( phandle, sw_params );
- if ( result < 0 ) {
- snd_pcm_close( phandle );
- errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
-#if defined(__RTAUDIO_DEBUG__)
- fprintf(stderr, "\nRtApiAlsa: dump software params after installation:\n\n");
- snd_pcm_sw_params_dump( sw_params, out );
-#endif
-
- // Set flags for buffer conversion
- stream_.doConvertBuffer[mode] = false;
- if ( stream_.userFormat != stream_.deviceFormat[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
- stream_.nUserChannels[mode] > 1 )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate the ApiHandle if necessary and then save.
- AlsaHandle *apiInfo = 0;
- if ( stream_.apiHandle == 0 ) {
- try {
- apiInfo = (AlsaHandle *) new AlsaHandle;
- }
- catch ( std::bad_alloc& ) {
- errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating AlsaHandle memory.";
- goto error;
- }
-
- if ( pthread_cond_init( &apiInfo->runnable_cv, NULL ) ) {
- errorText_ = "RtApiAlsa::probeDeviceOpen: error initializing pthread condition variable.";
- goto error;
- }
-
- stream_.apiHandle = (void *) apiInfo;
- apiInfo->handles[0] = 0;
- apiInfo->handles[1] = 0;
- }
- else {
- apiInfo = (AlsaHandle *) stream_.apiHandle;
- }
- apiInfo->handles[mode] = phandle;
- phandle = 0;
-
- // Allocate necessary internal buffers.
- unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- if ( stream_.doConvertBuffer[mode] ) {
-
- bool makeBuffer = true;
- bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- stream_.sampleRate = sampleRate;
- stream_.nBuffers = periods;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
-
- // Setup the buffer conversion information structure.
- if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
- // Setup thread if necessary.
- if ( stream_.mode == OUTPUT && mode == INPUT ) {
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- // Link the streams if possible.
- apiInfo->synchronized = false;
- if ( snd_pcm_link( apiInfo->handles[0], apiInfo->handles[1] ) == 0 )
- apiInfo->synchronized = true;
- else {
- errorText_ = "RtApiAlsa::probeDeviceOpen: unable to synchronize input and output devices.";
- error( RtError::WARNING );
- }
- }
- else {
- stream_.mode = mode;
-
- // Setup callback thread.
- stream_.callbackInfo.object = (void *) this;
-
- // Set the thread attributes for joinable and realtime scheduling
- // priority (optional). The higher priority will only take affect
- // if the program is run as root or suid. Note, under Linux
- // processes with CAP_SYS_NICE privilege, a user can change
- // scheduling policy and priority (thus need not be root). See
- // POSIX "capabilities".
- pthread_attr_t attr;
- pthread_attr_init( &attr );
- pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
-#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
- if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
- struct sched_param param;
- int priority = options->priority;
- int min = sched_get_priority_min( SCHED_RR );
- int max = sched_get_priority_max( SCHED_RR );
- if ( priority < min ) priority = min;
- else if ( priority > max ) priority = max;
- param.sched_priority = priority;
- pthread_attr_setschedparam( &attr, ¶m );
- pthread_attr_setschedpolicy( &attr, SCHED_RR );
- }
- else
- pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#else
- pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#endif
-
- stream_.callbackInfo.isRunning = true;
- result = pthread_create( &stream_.callbackInfo.thread, &attr, alsaCallbackHandler, &stream_.callbackInfo );
- pthread_attr_destroy( &attr );
- if ( result ) {
- stream_.callbackInfo.isRunning = false;
- errorText_ = "RtApiAlsa::error creating callback thread!";
- goto error;
- }
- }
-
- return SUCCESS;
-
- error:
- if ( apiInfo ) {
- pthread_cond_destroy( &apiInfo->runnable_cv );
- if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
- if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
- delete apiInfo;
- stream_.apiHandle = 0;
- }
-
- if ( phandle) snd_pcm_close( phandle );
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiAlsa :: closeStream()
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiAlsa::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
- stream_.callbackInfo.isRunning = false;
- MUTEX_LOCK( &stream_.mutex );
- if ( stream_.state == STREAM_STOPPED ) {
- apiInfo->runnable = true;
- pthread_cond_signal( &apiInfo->runnable_cv );
- }
- MUTEX_UNLOCK( &stream_.mutex );
- pthread_join( stream_.callbackInfo.thread, NULL );
-
- if ( stream_.state == STREAM_RUNNING ) {
- stream_.state = STREAM_STOPPED;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
- snd_pcm_drop( apiInfo->handles[0] );
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX )
- snd_pcm_drop( apiInfo->handles[1] );
- }
-
- if ( apiInfo ) {
- pthread_cond_destroy( &apiInfo->runnable_cv );
- if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] );
- if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] );
- delete apiInfo;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-void RtApiAlsa :: startStream()
-{
- // This method calls snd_pcm_prepare if the device isn't already in that state.
-
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiAlsa::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- int result = 0;
- snd_pcm_state_t state;
- AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
- snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- state = snd_pcm_state( handle[0] );
- if ( state != SND_PCM_STATE_PREPARED ) {
- result = snd_pcm_prepare( handle[0] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::startStream: error preparing output pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
- }
-
- if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
- state = snd_pcm_state( handle[1] );
- if ( state != SND_PCM_STATE_PREPARED ) {
- result = snd_pcm_prepare( handle[1] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::startStream: error preparing input pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
- }
-
- stream_.state = STREAM_RUNNING;
-
- unlock:
- apiInfo->runnable = true;
- pthread_cond_signal( &apiInfo->runnable_cv );
- MUTEX_UNLOCK( &stream_.mutex );
-
- if ( result >= 0 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: stopStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiAlsa::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_LOCK( &stream_.mutex );
-
- int result = 0;
- AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
- snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- if ( apiInfo->synchronized )
- result = snd_pcm_drop( handle[0] );
- else
- result = snd_pcm_drain( handle[0] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::stopStream: error draining output pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
- result = snd_pcm_drop( handle[1] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::stopStream: error stopping input pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- unlock:
- MUTEX_UNLOCK( &stream_.mutex );
-
- if ( result >= 0 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: abortStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiAlsa::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_LOCK( &stream_.mutex );
-
- int result = 0;
- AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
- snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- result = snd_pcm_drop( handle[0] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::abortStream: error aborting output pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) {
- result = snd_pcm_drop( handle[1] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::abortStream: error aborting input pcm device, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- unlock:
- MUTEX_UNLOCK( &stream_.mutex );
-
- if ( result >= 0 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiAlsa :: callbackEvent()
-{
- AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle;
- if ( stream_.state == STREAM_STOPPED ) {
- MUTEX_LOCK( &stream_.mutex );
- while ( !apiInfo->runnable )
- pthread_cond_wait( &apiInfo->runnable_cv, &stream_.mutex );
-
- if ( stream_.state != STREAM_RUNNING ) {
- MUTEX_UNLOCK( &stream_.mutex );
- return;
- }
- MUTEX_UNLOCK( &stream_.mutex );
- }
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiAlsa::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return;
- }
-
- int doStopStream = 0;
- RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && apiInfo->xrun[0] == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- apiInfo->xrun[0] = false;
- }
- if ( stream_.mode != OUTPUT && apiInfo->xrun[1] == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- apiInfo->xrun[1] = false;
- }
- doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
-
- if ( doStopStream == 2 ) {
- abortStream();
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- // The state might change while waiting on a mutex.
- if ( stream_.state == STREAM_STOPPED ) goto unlock;
-
- int result;
- char *buffer;
- int channels;
- snd_pcm_t **handle;
- snd_pcm_sframes_t frames;
- RtAudioFormat format;
- handle = (snd_pcm_t **) apiInfo->handles;
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- // Setup parameters.
- if ( stream_.doConvertBuffer[1] ) {
- buffer = stream_.deviceBuffer;
- channels = stream_.nDeviceChannels[1];
- format = stream_.deviceFormat[1];
- }
- else {
- buffer = stream_.userBuffer[1];
- channels = stream_.nUserChannels[1];
- format = stream_.userFormat;
- }
-
- // Read samples from device in interleaved/non-interleaved format.
- if ( stream_.deviceInterleaved[1] )
- result = snd_pcm_readi( handle[1], buffer, stream_.bufferSize );
- else {
- void *bufs[channels];
- size_t offset = stream_.bufferSize * formatBytes( format );
- for ( int i=0; ixrun[1] = true;
- result = snd_pcm_prepare( handle[1] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after overrun, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- }
- else {
- errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- }
- else {
- errorStream_ << "RtApiAlsa::callbackEvent: audio read error, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- error( RtError::WARNING );
- goto tryOutput;
- }
-
- // Do byte swapping if necessary.
- if ( stream_.doByteSwap[1] )
- byteSwapBuffer( buffer, stream_.bufferSize * channels, format );
-
- // Do buffer conversion if necessary.
- if ( stream_.doConvertBuffer[1] )
- convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
-
- // Check stream latency
- result = snd_pcm_delay( handle[1], &frames );
- if ( result == 0 && frames > 0 ) stream_.latency[1] = frames;
- }
-
- tryOutput:
-
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- // Setup parameters and do buffer conversion if necessary.
- if ( stream_.doConvertBuffer[0] ) {
- buffer = stream_.deviceBuffer;
- convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
- channels = stream_.nDeviceChannels[0];
- format = stream_.deviceFormat[0];
- }
- else {
- buffer = stream_.userBuffer[0];
- channels = stream_.nUserChannels[0];
- format = stream_.userFormat;
- }
-
- // Do byte swapping if necessary.
- if ( stream_.doByteSwap[0] )
- byteSwapBuffer(buffer, stream_.bufferSize * channels, format);
-
- // Write samples to device in interleaved/non-interleaved format.
- if ( stream_.deviceInterleaved[0] )
- result = snd_pcm_writei( handle[0], buffer, stream_.bufferSize );
- else {
- void *bufs[channels];
- size_t offset = stream_.bufferSize * formatBytes( format );
- for ( int i=0; ixrun[0] = true;
- result = snd_pcm_prepare( handle[0] );
- if ( result < 0 ) {
- errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- }
- else {
- errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- }
- else {
- errorStream_ << "RtApiAlsa::callbackEvent: audio write error, " << snd_strerror( result ) << ".";
- errorText_ = errorStream_.str();
- }
- error( RtError::WARNING );
- goto unlock;
- }
-
- // Check stream latency
- result = snd_pcm_delay( handle[0], &frames );
- if ( result == 0 && frames > 0 ) stream_.latency[0] = frames;
- }
-
- unlock:
- MUTEX_UNLOCK( &stream_.mutex );
-
- RtApi::tickStreamTime();
- if ( doStopStream == 1 ) this->stopStream();
-}
-
-extern "C" void *alsaCallbackHandler( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiAlsa *object = (RtApiAlsa *) info->object;
- bool *isRunning = &info->isRunning;
-
- while ( *isRunning == true ) {
- pthread_testcancel();
- object->callbackEvent();
- }
-
- pthread_exit( NULL );
-}
-
-//******************** End of __LINUX_ALSA__ *********************//
-#endif
-
-#if defined(__LINUX_PULSE__)
-
-// Code written by Peter Meerwald, pmeerw@pmeerw.net
-// and Tristan Matthews.
-
-#include
-#include
-#include
-
-namespace {
-const unsigned int SUPPORTED_SAMPLERATES[] = { 8000, 16000, 22050, 32000,
- 44100, 48000, 96000, 0}; }
-
-struct rtaudio_pa_format_mapping_t {
- RtAudioFormat rtaudio_format;
- pa_sample_format_t pa_format;
-};
-
-static const rtaudio_pa_format_mapping_t supported_sampleformats[] = {
- {RTAUDIO_SINT16, PA_SAMPLE_S16LE},
- {RTAUDIO_SINT32, PA_SAMPLE_S32LE},
- {RTAUDIO_FLOAT32, PA_SAMPLE_FLOAT32LE},
- {0, PA_SAMPLE_INVALID}};
-
-struct PulseAudioHandle {
- pa_simple *s_play;
- pa_simple *s_rec;
- pthread_t thread;
- pthread_cond_t runnable_cv;
- bool runnable;
- PulseAudioHandle() : s_play(0), s_rec(0), runnable(false) { }
-};
-
-RtApiPulse::~RtApiPulse()
-{
- if ( stream_.state != STREAM_CLOSED )
- closeStream();
-}
-
-unsigned int RtApiPulse::getDeviceCount( void )
-{
- return 1;
-}
-
-RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int device )
-{
- RtAudio::DeviceInfo info;
- info.probed = true;
- info.name = "PulseAudio";
- info.outputChannels = 2;
- info.inputChannels = 2;
- info.duplexChannels = 2;
- info.isDefaultOutput = true;
- info.isDefaultInput = true;
-
- for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
- info.sampleRates.push_back( *sr );
-
- info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
-
- return info;
-
- // unused
- (void)device;
-}
-
-extern "C" void *pulseaudio_callback( void * user )
-{
- CallbackInfo *cbi = static_cast( user );
- RtApiPulse *context = static_cast( cbi->object );
- volatile bool *isRunning = &cbi->isRunning;
-
- while ( *isRunning ) {
- pthread_testcancel();
- context->callbackEvent();
- }
-
- pthread_exit( NULL );
-}
-
-void RtApiPulse::closeStream( void )
-{
- PulseAudioHandle *pah = static_cast( stream_.apiHandle );
-
- stream_.callbackInfo.isRunning = false;
- if ( pah ) {
- MUTEX_LOCK( &stream_.mutex );
- if ( stream_.state == STREAM_STOPPED ) {
- pah->runnable = true;
- pthread_cond_signal( &pah->runnable_cv );
- }
- MUTEX_UNLOCK( &stream_.mutex );
-
- pthread_join( pah->thread, 0 );
- if ( pah->s_play ) {
- pa_simple_flush( pah->s_play, NULL );
- pa_simple_free( pah->s_play );
- }
- if ( pah->s_rec )
- pa_simple_free( pah->s_rec );
-
- pthread_cond_destroy( &pah->runnable_cv );
- delete pah;
- stream_.apiHandle = 0;
- }
-
- if ( stream_.userBuffer[0] ) {
- free( stream_.userBuffer[0] );
- stream_.userBuffer[0] = 0;
- }
- if ( stream_.userBuffer[1] ) {
- free( stream_.userBuffer[1] );
- stream_.userBuffer[1] = 0;
- }
-
- stream_.state = STREAM_CLOSED;
- stream_.mode = UNINITIALIZED;
-}
-
-void RtApiPulse::callbackEvent( void )
-{
- PulseAudioHandle *pah = static_cast( stream_.apiHandle );
-
- if ( stream_.state == STREAM_STOPPED ) {
- MUTEX_LOCK( &stream_.mutex );
- while ( !pah->runnable )
- pthread_cond_wait( &pah->runnable_cv, &stream_.mutex );
-
- if ( stream_.state != STREAM_RUNNING ) {
- MUTEX_UNLOCK( &stream_.mutex );
- return;
- }
- MUTEX_UNLOCK( &stream_.mutex );
- }
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiPulse::callbackEvent(): the stream is closed ... "
- "this shouldn't happen!";
- error( RtError::WARNING );
- return;
- }
-
- RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- int doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status,
- stream_.callbackInfo.userData );
-
- if ( doStopStream == 2 ) {
- abortStream();
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- if ( stream_.state != STREAM_RUNNING )
- goto unlock;
-
- int pa_error;
- size_t bytes;
- switch ( stream_.mode ) {
- case INPUT:
- bytes = stream_.nUserChannels[1] * stream_.bufferSize * formatBytes( stream_.userFormat );
- if ( pa_simple_read( pah->s_rec, stream_.userBuffer[1], bytes, &pa_error ) < 0 ) {
- errorStream_ << "RtApiPulse::callbackEvent: audio read error, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- }
- break;
- case OUTPUT:
- bytes = stream_.nUserChannels[0] * stream_.bufferSize * formatBytes( stream_.userFormat );
- if ( pa_simple_write( pah->s_play, stream_.userBuffer[0], bytes, &pa_error ) < 0 ) {
- errorStream_ << "RtApiPulse::callbackEvent: audio write error, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- }
- break;
- case DUPLEX:
- bytes = stream_.nUserChannels[1] * stream_.bufferSize * formatBytes( stream_.userFormat );
- if ( pa_simple_read( pah->s_rec, stream_.userBuffer[1], bytes, &pa_error ) < 0 ) {
- errorStream_ << "RtApiPulse::callbackEvent: audio read error, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- }
- bytes = stream_.nUserChannels[0] * stream_.bufferSize * formatBytes( stream_.userFormat );
- if ( pa_simple_write( pah->s_play, stream_.userBuffer[0], bytes, &pa_error ) < 0) {
- errorStream_ << "RtApiPulse::callbackEvent: audio write error, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- }
- break;
- default:
- // ERROR
- break;
- }
-
- unlock:
- MUTEX_UNLOCK( &stream_.mutex );
- RtApi::tickStreamTime();
-
- if ( doStopStream == 1 )
- stopStream();
-}
-
-void RtApiPulse::startStream( void )
-{
- PulseAudioHandle *pah = static_cast( stream_.apiHandle );
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiPulse::startStream(): the stream is not open!";
- error( RtError::INVALID_USE );
- return;
- }
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiPulse::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- stream_.state = STREAM_RUNNING;
-
- pah->runnable = true;
- pthread_cond_signal( &pah->runnable_cv );
- MUTEX_UNLOCK( &stream_.mutex );
-}
-
-void RtApiPulse::stopStream( void )
-{
- PulseAudioHandle *pah = static_cast( stream_.apiHandle );
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiPulse::stopStream(): the stream is not open!";
- error( RtError::INVALID_USE );
- return;
- }
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiPulse::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_LOCK( &stream_.mutex );
-
- if ( pah && pah->s_play ) {
- int pa_error;
- if ( pa_simple_drain( pah->s_play, &pa_error ) < 0 ) {
- errorStream_ << "RtApiPulse::stopStream: error draining output device, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- MUTEX_UNLOCK( &stream_.mutex );
- error( RtError::SYSTEM_ERROR );
- }
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_UNLOCK( &stream_.mutex );
-}
-
-void RtApiPulse::abortStream( void )
-{
- PulseAudioHandle *pah = static_cast( stream_.apiHandle );
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiPulse::abortStream(): the stream is not open!";
- error( RtError::INVALID_USE );
- return;
- }
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiPulse::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_LOCK( &stream_.mutex );
-
- if ( pah && pah->s_play ) {
- int pa_error;
- if ( pa_simple_flush( pah->s_play, &pa_error ) < 0 ) {
- errorStream_ << "RtApiPulse::abortStream: error flushing output device, " <<
- pa_strerror( pa_error ) << ".";
- errorText_ = errorStream_.str();
- MUTEX_UNLOCK( &stream_.mutex );
- error( RtError::SYSTEM_ERROR );
- }
- }
-
- stream_.state = STREAM_STOPPED;
- MUTEX_UNLOCK( &stream_.mutex );
-}
-
-bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
- unsigned int channels, unsigned int firstChannel,
- unsigned int sampleRate, RtAudioFormat format,
- unsigned int *bufferSize, RtAudio::StreamOptions *options )
-{
- PulseAudioHandle *pah = 0;
- unsigned long bufferBytes = 0;
- pa_sample_spec ss;
-
- if ( device != 0 ) return false;
- if ( mode != INPUT && mode != OUTPUT ) return false;
- if ( channels != 1 && channels != 2 ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: unsupported number of channels.";
- return false;
- }
- ss.channels = channels;
-
- if ( firstChannel != 0 ) return false;
-
- bool sr_found = false;
- for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) {
- if ( sampleRate == *sr ) {
- sr_found = true;
- stream_.sampleRate = sampleRate;
- ss.rate = sampleRate;
- break;
- }
- }
- if ( !sr_found ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample rate.";
- return false;
- }
-
- bool sf_found = 0;
- for ( const rtaudio_pa_format_mapping_t *sf = supported_sampleformats;
- sf->rtaudio_format && sf->pa_format != PA_SAMPLE_INVALID; ++sf ) {
- if ( format == sf->rtaudio_format ) {
- sf_found = true;
- stream_.userFormat = sf->rtaudio_format;
- ss.format = sf->pa_format;
- break;
- }
- }
- if ( !sf_found ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample format.";
- return false;
- }
-
- if ( options && ( options->flags & RTAUDIO_NONINTERLEAVED ) ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: only interleaved audio data supported.";
- return false;
- }
-
- stream_.userInterleaved = true;
- stream_.nBuffers = 1;
-
- stream_.deviceInterleaved[mode] = true;
- stream_.doByteSwap[mode] = false;
- stream_.doConvertBuffer[mode] = false;
- stream_.deviceFormat[mode] = stream_.userFormat;
- stream_.nUserChannels[mode] = channels;
- stream_.nDeviceChannels[mode] = channels;
- stream_.channelOffset[mode] = 0;
-
- // Allocate necessary internal buffers.
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
- stream_.bufferSize = *bufferSize;
-
- if ( !stream_.apiHandle ) {
- PulseAudioHandle *pah = new PulseAudioHandle;
- if ( !pah ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error allocating memory for handle.";
- goto error;
- }
-
- stream_.apiHandle = pah;
- if ( pthread_cond_init( &pah->runnable_cv, NULL ) != 0 ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error creating condition variable.";
- goto error;
- }
- }
- pah = static_cast( stream_.apiHandle );
-
- int error;
- switch ( mode ) {
- case INPUT:
- pah->s_rec = pa_simple_new( NULL, options->streamName.c_str(), PA_STREAM_RECORD, NULL, "Record", &ss, NULL, NULL, &error );
- if ( !pah->s_rec ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server.";
- goto error;
- }
- break;
- case OUTPUT:
- pah->s_play = pa_simple_new( NULL, options->streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error );
- if ( !pah->s_play ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server.";
- goto error;
- }
- break;
- default:
- goto error;
- }
-
- if ( stream_.mode == UNINITIALIZED )
- stream_.mode = mode;
- else if ( stream_.mode == mode )
- goto error;
- else
- stream_.mode = DUPLEX;
-
- stream_.state = STREAM_STOPPED;
-
- if ( !stream_.callbackInfo.isRunning ) {
- stream_.callbackInfo.object = this;
- stream_.callbackInfo.isRunning = true;
- if ( pthread_create( &pah->thread, NULL, pulseaudio_callback, (void *)&stream_.callbackInfo) != 0 ) {
- errorText_ = "RtApiPulse::probeDeviceOpen: error creating thread.";
- goto error;
- }
- }
- return true;
-
- error:
- closeStream();
- return false;
-}
-
-//******************** End of __LINUX_PULSE__ *********************//
-#endif
-
-#if defined(__LINUX_OSS__)
-
-#include
-#include
-#include
-#include
-#include "soundcard.h"
-#include
-#include
-
-extern "C" void *ossCallbackHandler(void * ptr);
-
-// A structure to hold various information related to the OSS API
-// implementation.
-struct OssHandle {
- int id[2]; // device ids
- bool xrun[2];
- bool triggered;
- pthread_cond_t runnable;
-
- OssHandle()
- :triggered(false) { id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; }
-};
-
-RtApiOss :: RtApiOss()
-{
- // Nothing to do here.
-}
-
-RtApiOss :: ~RtApiOss()
-{
- if ( stream_.state != STREAM_CLOSED ) closeStream();
-}
-
-unsigned int RtApiOss :: getDeviceCount( void )
-{
- int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
- if ( mixerfd == -1 ) {
- errorText_ = "RtApiOss::getDeviceCount: error opening '/dev/mixer'.";
- error( RtError::WARNING );
- return 0;
- }
-
- oss_sysinfo sysinfo;
- if ( ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ) == -1 ) {
- close( mixerfd );
- errorText_ = "RtApiOss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required.";
- error( RtError::WARNING );
- return 0;
- }
-
- close( mixerfd );
- return sysinfo.numaudios;
-}
-
-RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
-{
- RtAudio::DeviceInfo info;
- info.probed = false;
-
- int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
- if ( mixerfd == -1 ) {
- errorText_ = "RtApiOss::getDeviceInfo: error opening '/dev/mixer'.";
- error( RtError::WARNING );
- return info;
- }
-
- oss_sysinfo sysinfo;
- int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
- if ( result == -1 ) {
- close( mixerfd );
- errorText_ = "RtApiOss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required.";
- error( RtError::WARNING );
- return info;
- }
-
- unsigned nDevices = sysinfo.numaudios;
- if ( nDevices == 0 ) {
- close( mixerfd );
- errorText_ = "RtApiOss::getDeviceInfo: no devices found!";
- error( RtError::INVALID_USE );
- }
-
- if ( device >= nDevices ) {
- close( mixerfd );
- errorText_ = "RtApiOss::getDeviceInfo: device ID is invalid!";
- error( RtError::INVALID_USE );
- }
-
- oss_audioinfo ainfo;
- ainfo.dev = device;
- result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
- close( mixerfd );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Probe channels
- if ( ainfo.caps & PCM_CAP_OUTPUT ) info.outputChannels = ainfo.max_channels;
- if ( ainfo.caps & PCM_CAP_INPUT ) info.inputChannels = ainfo.max_channels;
- if ( ainfo.caps & PCM_CAP_DUPLEX ) {
- if ( info.outputChannels > 0 && info.inputChannels > 0 && ainfo.caps & PCM_CAP_DUPLEX )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
- }
-
- // Probe data formats ... do for input
- unsigned long mask = ainfo.iformats;
- if ( mask & AFMT_S16_LE || mask & AFMT_S16_BE )
- info.nativeFormats |= RTAUDIO_SINT16;
- if ( mask & AFMT_S8 )
- info.nativeFormats |= RTAUDIO_SINT8;
- if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE )
- info.nativeFormats |= RTAUDIO_SINT32;
- if ( mask & AFMT_FLOAT )
- info.nativeFormats |= RTAUDIO_FLOAT32;
- if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE )
- info.nativeFormats |= RTAUDIO_SINT24;
-
- // Check that we have at least one supported format
- if ( info.nativeFormats == 0 ) {
- errorStream_ << "RtApiOss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio.";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- return info;
- }
-
- // Probe the supported sample rates.
- info.sampleRates.clear();
- if ( ainfo.nrates ) {
- for ( unsigned int i=0; i= (int) SAMPLE_RATES[k] )
- info.sampleRates.push_back( SAMPLE_RATES[k] );
- }
- }
-
- if ( info.sampleRates.size() == 0 ) {
- errorStream_ << "RtApiOss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- error( RtError::WARNING );
- }
- else {
- info.probed = true;
- info.name = ainfo.name;
- }
-
- return info;
-}
-
-
-bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options )
-{
- int mixerfd = open( "/dev/mixer", O_RDWR, 0 );
- if ( mixerfd == -1 ) {
- errorText_ = "RtApiOss::probeDeviceOpen: error opening '/dev/mixer'.";
- return FAILURE;
- }
-
- oss_sysinfo sysinfo;
- int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo );
- if ( result == -1 ) {
- close( mixerfd );
- errorText_ = "RtApiOss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required.";
- return FAILURE;
- }
-
- unsigned nDevices = sysinfo.numaudios;
- if ( nDevices == 0 ) {
- // This should not happen because a check is made before this function is called.
- close( mixerfd );
- errorText_ = "RtApiOss::probeDeviceOpen: no devices found!";
- return FAILURE;
- }
-
- if ( device >= nDevices ) {
- // This should not happen because a check is made before this function is called.
- close( mixerfd );
- errorText_ = "RtApiOss::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
-
- oss_audioinfo ainfo;
- ainfo.dev = device;
- result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo );
- close( mixerfd );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Check if device supports input or output
- if ( ( mode == OUTPUT && !( ainfo.caps & PCM_CAP_OUTPUT ) ) ||
- ( mode == INPUT && !( ainfo.caps & PCM_CAP_INPUT ) ) ) {
- if ( mode == OUTPUT )
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support output.";
- else
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support input.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- int flags = 0;
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- if ( mode == OUTPUT )
- flags |= O_WRONLY;
- else { // mode == INPUT
- if (stream_.mode == OUTPUT && stream_.device[0] == device) {
- // We just set the same device for playback ... close and reopen for duplex (OSS only).
- close( handle->id[0] );
- handle->id[0] = 0;
- if ( !( ainfo.caps & PCM_CAP_DUPLEX ) ) {
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- // Check that the number previously set channels is the same.
- if ( stream_.nUserChannels[0] != channels ) {
- errorStream_ << "RtApiOss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- flags |= O_RDWR;
- }
- else
- flags |= O_RDONLY;
- }
-
- // Set exclusive access if specified.
- if ( options && options->flags & RTAUDIO_HOG_DEVICE ) flags |= O_EXCL;
-
- // Try to open the device.
- int fd;
- fd = open( ainfo.devnode, flags, 0 );
- if ( fd == -1 ) {
- if ( errno == EBUSY )
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") is busy.";
- else
- errorStream_ << "RtApiOss::probeDeviceOpen: error opening device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // For duplex operation, specifically set this mode (this doesn't seem to work).
- /*
- if ( flags | O_RDWR ) {
- result = ioctl( fd, SNDCTL_DSP_SETDUPLEX, NULL );
- if ( result == -1) {
- errorStream_ << "RtApiOss::probeDeviceOpen: error setting duplex mode for device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- }
- */
-
- // Check the device channel support.
- stream_.nUserChannels[mode] = channels;
- if ( ainfo.max_channels < (int)(channels + firstChannel) ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the number of channels.
- int deviceChannels = channels + firstChannel;
- result = ioctl( fd, SNDCTL_DSP_CHANNELS, &deviceChannels );
- if ( result == -1 || deviceChannels < (int)(channels + firstChannel) ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- stream_.nDeviceChannels[mode] = deviceChannels;
-
- // Get the data format mask
- int mask;
- result = ioctl( fd, SNDCTL_DSP_GETFMTS, &mask );
- if ( result == -1 ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Determine how to set the device format.
- stream_.userFormat = format;
- int deviceFormat = -1;
- stream_.doByteSwap[mode] = false;
- if ( format == RTAUDIO_SINT8 ) {
- if ( mask & AFMT_S8 ) {
- deviceFormat = AFMT_S8;
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- }
- }
- else if ( format == RTAUDIO_SINT16 ) {
- if ( mask & AFMT_S16_NE ) {
- deviceFormat = AFMT_S16_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- }
- else if ( mask & AFMT_S16_OE ) {
- deviceFormat = AFMT_S16_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- stream_.doByteSwap[mode] = true;
- }
- }
- else if ( format == RTAUDIO_SINT24 ) {
- if ( mask & AFMT_S24_NE ) {
- deviceFormat = AFMT_S24_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT24;
- }
- else if ( mask & AFMT_S24_OE ) {
- deviceFormat = AFMT_S24_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT24;
- stream_.doByteSwap[mode] = true;
- }
- }
- else if ( format == RTAUDIO_SINT32 ) {
- if ( mask & AFMT_S32_NE ) {
- deviceFormat = AFMT_S32_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- }
- else if ( mask & AFMT_S32_OE ) {
- deviceFormat = AFMT_S32_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- stream_.doByteSwap[mode] = true;
- }
- }
-
- if ( deviceFormat == -1 ) {
- // The user requested format is not natively supported by the device.
- if ( mask & AFMT_S16_NE ) {
- deviceFormat = AFMT_S16_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- }
- else if ( mask & AFMT_S32_NE ) {
- deviceFormat = AFMT_S32_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- }
- else if ( mask & AFMT_S24_NE ) {
- deviceFormat = AFMT_S24_NE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT24;
- }
- else if ( mask & AFMT_S16_OE ) {
- deviceFormat = AFMT_S16_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT16;
- stream_.doByteSwap[mode] = true;
- }
- else if ( mask & AFMT_S32_OE ) {
- deviceFormat = AFMT_S32_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT32;
- stream_.doByteSwap[mode] = true;
- }
- else if ( mask & AFMT_S24_OE ) {
- deviceFormat = AFMT_S24_OE;
- stream_.deviceFormat[mode] = RTAUDIO_SINT24;
- stream_.doByteSwap[mode] = true;
- }
- else if ( mask & AFMT_S8) {
- deviceFormat = AFMT_S8;
- stream_.deviceFormat[mode] = RTAUDIO_SINT8;
- }
- }
-
- if ( stream_.deviceFormat[mode] == 0 ) {
- // This really shouldn't happen ...
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio.";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Set the data format.
- int temp = deviceFormat;
- result = ioctl( fd, SNDCTL_DSP_SETFMT, &deviceFormat );
- if ( result == -1 || deviceFormat != temp ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Attempt to set the buffer size. According to OSS, the minimum
- // number of buffers is two. The supposed minimum buffer size is 16
- // bytes, so that will be our lower bound. The argument to this
- // call is in the form 0xMMMMSSSS (hex), where the buffer size (in
- // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM.
- // We'll check the actual value used near the end of the setup
- // procedure.
- int ossBufferBytes = *bufferSize * formatBytes( stream_.deviceFormat[mode] ) * deviceChannels;
- if ( ossBufferBytes < 16 ) ossBufferBytes = 16;
- int buffers = 0;
- if ( options ) buffers = options->numberOfBuffers;
- if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) buffers = 2;
- if ( buffers < 2 ) buffers = 3;
- temp = ((int) buffers << 16) + (int)( log10( (double)ossBufferBytes ) / log10( 2.0 ) );
- result = ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &temp );
- if ( result == -1 ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- stream_.nBuffers = buffers;
-
- // Save buffer size (in sample frames).
- *bufferSize = ossBufferBytes / ( formatBytes(stream_.deviceFormat[mode]) * deviceChannels );
- stream_.bufferSize = *bufferSize;
-
- // Set the sample rate.
- int srate = sampleRate;
- result = ioctl( fd, SNDCTL_DSP_SPEED, &srate );
- if ( result == -1 ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: error setting sample rate (" << sampleRate << ") on device (" << ainfo.name << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
- // Verify the sample rate setup worked.
- if ( abs( srate - sampleRate ) > 100 ) {
- close( fd );
- errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
- stream_.sampleRate = sampleRate;
-
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) {
- // We're doing duplex setup here.
- stream_.deviceFormat[0] = stream_.deviceFormat[1];
- stream_.nDeviceChannels[0] = deviceChannels;
- }
-
- // Set interleaving parameters.
- stream_.userInterleaved = true;
- stream_.deviceInterleaved[mode] = true;
- if ( options && options->flags & RTAUDIO_NONINTERLEAVED )
- stream_.userInterleaved = false;
-
- // Set flags for buffer conversion
- stream_.doConvertBuffer[mode] = false;
- if ( stream_.userFormat != stream_.deviceFormat[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] )
- stream_.doConvertBuffer[mode] = true;
- if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] &&
- stream_.nUserChannels[mode] > 1 )
- stream_.doConvertBuffer[mode] = true;
-
- // Allocate the stream handles if necessary and then save.
- if ( stream_.apiHandle == 0 ) {
- try {
- handle = new OssHandle;
- }
- catch ( std::bad_alloc& ) {
- errorText_ = "RtApiOss::probeDeviceOpen: error allocating OssHandle memory.";
- goto error;
- }
-
- if ( pthread_cond_init( &handle->runnable, NULL ) ) {
- errorText_ = "RtApiOss::probeDeviceOpen: error initializing pthread condition variable.";
- goto error;
- }
-
- stream_.apiHandle = (void *) handle;
- }
- else {
- handle = (OssHandle *) stream_.apiHandle;
- }
- handle->id[mode] = fd;
-
- // Allocate necessary internal buffers.
- unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
- stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
- if ( stream_.userBuffer[mode] == NULL ) {
- errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory.";
- goto error;
- }
-
- if ( stream_.doConvertBuffer[mode] ) {
-
- bool makeBuffer = true;
- bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
- }
-
- if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
- if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
- stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
- if ( stream_.deviceBuffer == NULL ) {
- errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory.";
- goto error;
- }
- }
- }
-
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
-
- // Setup the buffer conversion information structure.
- if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel );
-
- // Setup thread if necessary.
- if ( stream_.mode == OUTPUT && mode == INPUT ) {
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- if ( stream_.device[0] == device ) handle->id[0] = fd;
- }
- else {
- stream_.mode = mode;
-
- // Setup callback thread.
- stream_.callbackInfo.object = (void *) this;
-
- // Set the thread attributes for joinable and realtime scheduling
- // priority. The higher priority will only take affect if the
- // program is run as root or suid.
- pthread_attr_t attr;
- pthread_attr_init( &attr );
- pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
-#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread)
- if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) {
- struct sched_param param;
- int priority = options->priority;
- int min = sched_get_priority_min( SCHED_RR );
- int max = sched_get_priority_max( SCHED_RR );
- if ( priority < min ) priority = min;
- else if ( priority > max ) priority = max;
- param.sched_priority = priority;
- pthread_attr_setschedparam( &attr, ¶m );
- pthread_attr_setschedpolicy( &attr, SCHED_RR );
- }
- else
- pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#else
- pthread_attr_setschedpolicy( &attr, SCHED_OTHER );
-#endif
-
- stream_.callbackInfo.isRunning = true;
- result = pthread_create( &stream_.callbackInfo.thread, &attr, ossCallbackHandler, &stream_.callbackInfo );
- pthread_attr_destroy( &attr );
- if ( result ) {
- stream_.callbackInfo.isRunning = false;
- errorText_ = "RtApiOss::error creating callback thread!";
- goto error;
- }
- }
-
- return SUCCESS;
-
- error:
- if ( handle ) {
- pthread_cond_destroy( &handle->runnable );
- if ( handle->id[0] ) close( handle->id[0] );
- if ( handle->id[1] ) close( handle->id[1] );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- return FAILURE;
-}
-
-void RtApiOss :: closeStream()
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiOss::closeStream(): no open stream to close!";
- error( RtError::WARNING );
- return;
- }
-
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- stream_.callbackInfo.isRunning = false;
- MUTEX_LOCK( &stream_.mutex );
- if ( stream_.state == STREAM_STOPPED )
- pthread_cond_signal( &handle->runnable );
- MUTEX_UNLOCK( &stream_.mutex );
- pthread_join( stream_.callbackInfo.thread, NULL );
-
- if ( stream_.state == STREAM_RUNNING ) {
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX )
- ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
- else
- ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
- stream_.state = STREAM_STOPPED;
- }
-
- if ( handle ) {
- pthread_cond_destroy( &handle->runnable );
- if ( handle->id[0] ) close( handle->id[0] );
- if ( handle->id[1] ) close( handle->id[1] );
- delete handle;
- stream_.apiHandle = 0;
- }
-
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
- }
- }
-
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
- }
-
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
-}
-
-void RtApiOss :: startStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_RUNNING ) {
- errorText_ = "RtApiOss::startStream(): the stream is already running!";
- error( RtError::WARNING );
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- stream_.state = STREAM_RUNNING;
-
- // No need to do anything else here ... OSS automatically starts
- // when fed samples.
-
- MUTEX_UNLOCK( &stream_.mutex );
-
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- pthread_cond_signal( &handle->runnable );
-}
-
-void RtApiOss :: stopStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiOss::stopStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- // The state might change while waiting on a mutex.
- if ( stream_.state == STREAM_STOPPED ) {
- MUTEX_UNLOCK( &stream_.mutex );
- return;
- }
-
- int result = 0;
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- // Flush the output with zeros a few times.
- char *buffer;
- int samples;
- RtAudioFormat format;
-
- if ( stream_.doConvertBuffer[0] ) {
- buffer = stream_.deviceBuffer;
- samples = stream_.bufferSize * stream_.nDeviceChannels[0];
- format = stream_.deviceFormat[0];
- }
- else {
- buffer = stream_.userBuffer[0];
- samples = stream_.bufferSize * stream_.nUserChannels[0];
- format = stream_.userFormat;
- }
-
- memset( buffer, 0, samples * formatBytes(format) );
- for ( unsigned int i=0; iid[0], buffer, samples * formatBytes(format) );
- if ( result == -1 ) {
- errorText_ = "RtApiOss::stopStream: audio write error.";
- error( RtError::WARNING );
- }
- }
-
- result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::stopStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- handle->triggered = false;
- }
-
- if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
- result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::stopStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- unlock:
- stream_.state = STREAM_STOPPED;
- MUTEX_UNLOCK( &stream_.mutex );
-
- if ( result != -1 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiOss :: abortStream()
-{
- verifyStream();
- if ( stream_.state == STREAM_STOPPED ) {
- errorText_ = "RtApiOss::abortStream(): the stream is already stopped!";
- error( RtError::WARNING );
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- // The state might change while waiting on a mutex.
- if ( stream_.state == STREAM_STOPPED ) {
- MUTEX_UNLOCK( &stream_.mutex );
- return;
- }
-
- int result = 0;
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
- result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::abortStream: system error stopping callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- handle->triggered = false;
- }
-
- if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) {
- result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 );
- if ( result == -1 ) {
- errorStream_ << "RtApiOss::abortStream: system error stopping input callback procedure on device (" << stream_.device[0] << ").";
- errorText_ = errorStream_.str();
- goto unlock;
- }
- }
-
- unlock:
- stream_.state = STREAM_STOPPED;
- MUTEX_UNLOCK( &stream_.mutex );
-
- if ( result != -1 ) return;
- error( RtError::SYSTEM_ERROR );
-}
-
-void RtApiOss :: callbackEvent()
-{
- OssHandle *handle = (OssHandle *) stream_.apiHandle;
- if ( stream_.state == STREAM_STOPPED ) {
- MUTEX_LOCK( &stream_.mutex );
- pthread_cond_wait( &handle->runnable, &stream_.mutex );
- if ( stream_.state != STREAM_RUNNING ) {
- MUTEX_UNLOCK( &stream_.mutex );
- return;
- }
- MUTEX_UNLOCK( &stream_.mutex );
- }
-
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApiOss::callbackEvent(): the stream is closed ... this shouldn't happen!";
- error( RtError::WARNING );
- return;
- }
-
- // Invoke user callback to get fresh output data.
- int doStopStream = 0;
- RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback;
- double streamTime = getStreamTime();
- RtAudioStreamStatus status = 0;
- if ( stream_.mode != INPUT && handle->xrun[0] == true ) {
- status |= RTAUDIO_OUTPUT_UNDERFLOW;
- handle->xrun[0] = false;
- }
- if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) {
- status |= RTAUDIO_INPUT_OVERFLOW;
- handle->xrun[1] = false;
- }
- doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData );
- if ( doStopStream == 2 ) {
- this->abortStream();
- return;
- }
-
- MUTEX_LOCK( &stream_.mutex );
-
- // The state might change while waiting on a mutex.
- if ( stream_.state == STREAM_STOPPED ) goto unlock;
-
- int result;
- char *buffer;
- int samples;
- RtAudioFormat format;
-
- if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
-
- // Setup parameters and do buffer conversion if necessary.
- if ( stream_.doConvertBuffer[0] ) {
- buffer = stream_.deviceBuffer;
- convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] );
- samples = stream_.bufferSize * stream_.nDeviceChannels[0];
- format = stream_.deviceFormat[0];
- }
- else {
- buffer = stream_.userBuffer[0];
- samples = stream_.bufferSize * stream_.nUserChannels[0];
- format = stream_.userFormat;
- }
-
- // Do byte swapping if necessary.
- if ( stream_.doByteSwap[0] )
- byteSwapBuffer( buffer, samples, format );
-
- if ( stream_.mode == DUPLEX && handle->triggered == false ) {
- int trig = 0;
- ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
- result = write( handle->id[0], buffer, samples * formatBytes(format) );
- trig = PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT;
- ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig );
- handle->triggered = true;
- }
- else
- // Write samples to device.
- result = write( handle->id[0], buffer, samples * formatBytes(format) );
-
- if ( result == -1 ) {
- // We'll assume this is an underrun, though there isn't a
- // specific means for determining that.
- handle->xrun[0] = true;
- errorText_ = "RtApiOss::callbackEvent: audio write error.";
- error( RtError::WARNING );
- // Continue on to input section.
- }
- }
-
- if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) {
-
- // Setup parameters.
- if ( stream_.doConvertBuffer[1] ) {
- buffer = stream_.deviceBuffer;
- samples = stream_.bufferSize * stream_.nDeviceChannels[1];
- format = stream_.deviceFormat[1];
- }
- else {
- buffer = stream_.userBuffer[1];
- samples = stream_.bufferSize * stream_.nUserChannels[1];
- format = stream_.userFormat;
- }
-
- // Read samples from device.
- result = read( handle->id[1], buffer, samples * formatBytes(format) );
-
- if ( result == -1 ) {
- // We'll assume this is an overrun, though there isn't a
- // specific means for determining that.
- handle->xrun[1] = true;
- errorText_ = "RtApiOss::callbackEvent: audio read error.";
- error( RtError::WARNING );
- goto unlock;
- }
-
- // Do byte swapping if necessary.
- if ( stream_.doByteSwap[1] )
- byteSwapBuffer( buffer, samples, format );
-
- // Do buffer conversion if necessary.
- if ( stream_.doConvertBuffer[1] )
- convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] );
- }
-
- unlock:
- MUTEX_UNLOCK( &stream_.mutex );
-
- RtApi::tickStreamTime();
- if ( doStopStream == 1 ) this->stopStream();
-}
-
-extern "C" void *ossCallbackHandler( void *ptr )
-{
- CallbackInfo *info = (CallbackInfo *) ptr;
- RtApiOss *object = (RtApiOss *) info->object;
- bool *isRunning = &info->isRunning;
-
- while ( *isRunning == true ) {
- pthread_testcancel();
- object->callbackEvent();
- }
-
- pthread_exit( NULL );
-}
-
-//******************** End of __LINUX_OSS__ *********************//
-#endif
-
-
-// *************************************************** //
-//
-// Protected common (OS-independent) RtAudio methods.
-//
-// *************************************************** //
-
-// This method can be modified to control the behavior of error
-// message printing.
-void RtApi :: error( RtError::Type type )
-{
- errorStream_.str(""); // clear the ostringstream
- if ( type == RtError::WARNING && showWarnings_ == true )
- std::cerr << '\n' << errorText_ << "\n\n";
- else if ( type != RtError::WARNING )
- throw( RtError( errorText_, type ) );
-}
-
-void RtApi :: verifyStream()
-{
- if ( stream_.state == STREAM_CLOSED ) {
- errorText_ = "RtApi:: a stream is not open!";
- error( RtError::INVALID_USE );
- }
-}
-
-void RtApi :: clearStreamInfo()
-{
- stream_.mode = UNINITIALIZED;
- stream_.state = STREAM_CLOSED;
- stream_.sampleRate = 0;
- stream_.bufferSize = 0;
- stream_.nBuffers = 0;
- stream_.userFormat = 0;
- stream_.userInterleaved = true;
- stream_.streamTime = 0.0;
- stream_.apiHandle = 0;
- stream_.deviceBuffer = 0;
- stream_.callbackInfo.callback = 0;
- stream_.callbackInfo.userData = 0;
- stream_.callbackInfo.isRunning = false;
- for ( int i=0; i<2; i++ ) {
- stream_.device[i] = 11111;
- stream_.doConvertBuffer[i] = false;
- stream_.deviceInterleaved[i] = true;
- stream_.doByteSwap[i] = false;
- stream_.nUserChannels[i] = 0;
- stream_.nDeviceChannels[i] = 0;
- stream_.channelOffset[i] = 0;
- stream_.deviceFormat[i] = 0;
- stream_.latency[i] = 0;
- stream_.userBuffer[i] = 0;
- stream_.convertInfo[i].channels = 0;
- stream_.convertInfo[i].inJump = 0;
- stream_.convertInfo[i].outJump = 0;
- stream_.convertInfo[i].inFormat = 0;
- stream_.convertInfo[i].outFormat = 0;
- stream_.convertInfo[i].inOffset.clear();
- stream_.convertInfo[i].outOffset.clear();
- }
-}
-
-unsigned int RtApi :: formatBytes( RtAudioFormat format )
-{
- if ( format == RTAUDIO_SINT16 )
- return 2;
- else if ( format == RTAUDIO_SINT24 || format == RTAUDIO_SINT32 ||
- format == RTAUDIO_FLOAT32 )
- return 4;
- else if ( format == RTAUDIO_FLOAT64 )
- return 8;
- else if ( format == RTAUDIO_SINT8 )
- return 1;
-
- errorText_ = "RtApi::formatBytes: undefined format.";
- error( RtError::WARNING );
-
- return 0;
-}
-
-void RtApi :: setConvertInfo( StreamMode mode, unsigned int firstChannel )
-{
- if ( mode == INPUT ) { // convert device to user buffer
- stream_.convertInfo[mode].inJump = stream_.nDeviceChannels[1];
- stream_.convertInfo[mode].outJump = stream_.nUserChannels[1];
- stream_.convertInfo[mode].inFormat = stream_.deviceFormat[1];
- stream_.convertInfo[mode].outFormat = stream_.userFormat;
- }
- else { // convert user to device buffer
- stream_.convertInfo[mode].inJump = stream_.nUserChannels[0];
- stream_.convertInfo[mode].outJump = stream_.nDeviceChannels[0];
- stream_.convertInfo[mode].inFormat = stream_.userFormat;
- stream_.convertInfo[mode].outFormat = stream_.deviceFormat[0];
- }
-
- if ( stream_.convertInfo[mode].inJump < stream_.convertInfo[mode].outJump )
- stream_.convertInfo[mode].channels = stream_.convertInfo[mode].inJump;
- else
- stream_.convertInfo[mode].channels = stream_.convertInfo[mode].outJump;
-
- // Set up the interleave/deinterleave offsets.
- if ( stream_.deviceInterleaved[mode] != stream_.userInterleaved ) {
- if ( ( mode == OUTPUT && stream_.deviceInterleaved[mode] ) ||
- ( mode == INPUT && stream_.userInterleaved ) ) {
- for ( int k=0; k 0 ) {
- if ( stream_.deviceInterleaved[mode] ) {
- if ( mode == OUTPUT ) {
- for ( int k=0; k>= 8;
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_FLOAT32) {
- Float32 *in = (Float32 *)inBuffer;
- for (unsigned int i=0; i> 8) & 0x0000ffff);
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_SINT32) {
- Int32 *in = (Int32 *)inBuffer;
- for (unsigned int i=0; i> 16) & 0x0000ffff);
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_FLOAT32) {
- Float32 *in = (Float32 *)inBuffer;
- for (unsigned int i=0; i> 8) & 0x00ff);
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_SINT24) {
- Int32 *in = (Int32 *)inBuffer;
- for (unsigned int i=0; i> 16) & 0x000000ff);
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_SINT32) {
- Int32 *in = (Int32 *)inBuffer;
- for (unsigned int i=0; i> 24) & 0x000000ff);
- }
- in += info.inJump;
- out += info.outJump;
- }
- }
- else if (info.inFormat == RTAUDIO_FLOAT32) {
- Float32 *in = (Float32 *)inBuffer;
- for (unsigned int i=0; i>8) | (x<<8); }
- //static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); }
- //static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); }
-
-void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format )
-{
- register char val;
- register char *ptr;
-
- ptr = buffer;
- if ( format == RTAUDIO_SINT16 ) {
- for ( unsigned int i=0; i
-#include
-#include "RtError.h"
-
-/*! \typedef typedef unsigned long RtAudioFormat;
- \brief RtAudio data format type.
-
- Support for signed integers and floats. Audio data fed to/from an
- RtAudio stream is assumed to ALWAYS be in host byte order. The
- internal routines will automatically take care of any necessary
- byte-swapping between the host format and the soundcard. Thus,
- endian-ness is not a concern in the following format definitions.
- Note that 24-bit data is expected to be encapsulated in a 32-bit
- format.
-
- - \e RTAUDIO_SINT8: 8-bit signed integer.
- - \e RTAUDIO_SINT16: 16-bit signed integer.
- - \e RTAUDIO_SINT24: Lower 3 bytes of 32-bit signed integer.
- - \e RTAUDIO_SINT32: 32-bit signed integer.
- - \e RTAUDIO_FLOAT32: Normalized between plus/minus 1.0.
- - \e RTAUDIO_FLOAT64: Normalized between plus/minus 1.0.
-*/
-typedef unsigned long RtAudioFormat;
-static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // Lower 3 bytes of 32-bit signed integer.
-static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer.
-static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
-static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
-
-/*! \typedef typedef unsigned long RtAudioStreamFlags;
- \brief RtAudio stream option flags.
-
- The following flags can be OR'ed together to allow a client to
- make changes to the default stream behavior:
-
- - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
- - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
- - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
- - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
-
- By default, RtAudio streams pass and receive audio data from the
- client in an interleaved format. By passing the
- RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
- data will instead be presented in non-interleaved buffers. In
- this case, each buffer argument in the RtAudioCallback function
- will point to a single array of data, with \c nFrames samples for
- each channel concatenated back-to-back. For example, the first
- sample of data for the second channel would be located at index \c
- nFrames (assuming the \c buffer pointer was recast to the correct
- data type for the stream).
-
- Certain audio APIs offer a number of parameters that influence the
- I/O latency of a stream. By default, RtAudio will attempt to set
- these parameters internally for robust (glitch-free) performance
- (though some APIs, like Windows Direct Sound, make this difficult).
- By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
- function, internal stream settings will be influenced in an attempt
- to minimize stream latency, though possibly at the expense of stream
- performance.
-
- If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
- open the input and/or output stream device(s) for exclusive use.
- Note that this is not possible with all supported audio APIs.
-
- If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
- to select realtime scheduling (round-robin) for the callback thread.
-
- If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
- open the "default" PCM device when using the ALSA API. Note that this
- will override any specified input or output device id.
-*/
-typedef unsigned int RtAudioStreamFlags;
-static const RtAudioStreamFlags RTAUDIO_NONINTERLEAVED = 0x1; // Use non-interleaved buffers (default = interleaved).
-static const RtAudioStreamFlags RTAUDIO_MINIMIZE_LATENCY = 0x2; // Attempt to set stream parameters for lowest possible latency.
-static const RtAudioStreamFlags RTAUDIO_HOG_DEVICE = 0x4; // Attempt grab device and prevent use by others.
-static const RtAudioStreamFlags RTAUDIO_SCHEDULE_REALTIME = 0x8; // Try to select realtime scheduling for callback thread.
-static const RtAudioStreamFlags RTAUDIO_ALSA_USE_DEFAULT = 0x10; // Use the "default" PCM device (ALSA only).
-
-/*! \typedef typedef unsigned long RtAudioStreamStatus;
- \brief RtAudio stream status (over- or underflow) flags.
-
- Notification of a stream over- or underflow is indicated by a
- non-zero stream \c status argument in the RtAudioCallback function.
- The stream status can be one of the following two options,
- depending on whether the stream is open for output and/or input:
-
- - \e RTAUDIO_INPUT_OVERFLOW: Input data was discarded because of an overflow condition at the driver.
- - \e RTAUDIO_OUTPUT_UNDERFLOW: The output buffer ran low, likely producing a break in the output sound.
-*/
-typedef unsigned int RtAudioStreamStatus;
-static const RtAudioStreamStatus RTAUDIO_INPUT_OVERFLOW = 0x1; // Input data was discarded because of an overflow condition at the driver.
-static const RtAudioStreamStatus RTAUDIO_OUTPUT_UNDERFLOW = 0x2; // The output buffer ran low, likely causing a gap in the output sound.
-
-//! RtAudio callback function prototype.
-/*!
- All RtAudio clients must create a function of type RtAudioCallback
- to read and/or write data from/to the audio stream. When the
- underlying audio system is ready for new input or output data, this
- function will be invoked.
-
- \param outputBuffer For output (or duplex) streams, the client
- should write \c nFrames of audio sample frames into this
- buffer. This argument should be recast to the datatype
- specified when the stream was opened. For input-only
- streams, this argument will be NULL.
-
- \param inputBuffer For input (or duplex) streams, this buffer will
- hold \c nFrames of input audio sample frames. This
- argument should be recast to the datatype specified when the
- stream was opened. For output-only streams, this argument
- will be NULL.
-
- \param nFrames The number of sample frames of input or output
- data in the buffers. The actual buffer size in bytes is
- dependent on the data type and number of channels in use.
-
- \param streamTime The number of seconds that have elapsed since the
- stream was started.
-
- \param status If non-zero, this argument indicates a data overflow
- or underflow condition for the stream. The particular
- condition can be determined by comparison with the
- RtAudioStreamStatus flags.
-
- \param userData A pointer to optional data provided by the client
- when opening the stream (default = NULL).
-
- To continue normal stream operation, the RtAudioCallback function
- should return a value of zero. To stop the stream and drain the
- output buffer, the function should return a value of one. To abort
- the stream immediately, the client should return a value of two.
- */
-typedef int (*RtAudioCallback)( void *outputBuffer, void *inputBuffer,
- unsigned int nFrames,
- double streamTime,
- RtAudioStreamStatus status,
- void *userData );
-
-
-// **************************************************************** //
-//
-// RtAudio class declaration.
-//
-// RtAudio is a "controller" used to select an available audio i/o
-// interface. It presents a common API for the user to call but all
-// functionality is implemented by the class RtApi and its
-// subclasses. RtAudio creates an instance of an RtApi subclass
-// based on the user's API choice. If no choice is made, RtAudio
-// attempts to make a "logical" API selection.
-//
-// **************************************************************** //
-
-class RtApi;
-
-class RtAudio
-{
- public:
-
- //! Audio API specifier arguments.
- enum Api {
- UNSPECIFIED, /*!< Search for a working compiled API. */
- LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */
- LINUX_PULSE, /*!< The Linux PulseAudio API. */
- LINUX_OSS, /*!< The Linux Open Sound System API. */
- UNIX_JACK, /*!< The Jack Low-Latency Audio Server API. */
- MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */
- WINDOWS_ASIO, /*!< The Steinberg Audio Stream I/O API. */
- WINDOWS_DS, /*!< The Microsoft Direct Sound API. */
- RTAUDIO_DUMMY /*!< A compilable but non-functional API. */
- };
-
- //! The public device information structure for returning queried values.
- struct DeviceInfo {
- bool probed; /*!< true if the device capabilities were successfully probed. */
- std::string name; /*!< Character string device identifier. */
- unsigned int outputChannels; /*!< Maximum output channels supported by device. */
- unsigned int inputChannels; /*!< Maximum input channels supported by device. */
- unsigned int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */
- bool isDefaultOutput; /*!< true if this is the default output device. */
- bool isDefaultInput; /*!< true if this is the default input device. */
- std::vector sampleRates; /*!< Supported sample rates (queried from list of standard rates). */
- RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
-
- // Default constructor.
- DeviceInfo()
- :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0),
- isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {}
- };
-
- //! The structure for specifying input or ouput stream parameters.
- struct StreamParameters {
- unsigned int deviceId; /*!< Device index (0 to getDeviceCount() - 1). */
- unsigned int nChannels; /*!< Number of channels. */
- unsigned int firstChannel; /*!< First channel index on device (default = 0). */
-
- // Default constructor.
- StreamParameters()
- : deviceId(0), nChannels(0), firstChannel(0) {}
- };
-
- //! The structure for specifying stream options.
- /*!
- The following flags can be OR'ed together to allow a client to
- make changes to the default stream behavior:
-
- - \e RTAUDIO_NONINTERLEAVED: Use non-interleaved buffers (default = interleaved).
- - \e RTAUDIO_MINIMIZE_LATENCY: Attempt to set stream parameters for lowest possible latency.
- - \e RTAUDIO_HOG_DEVICE: Attempt grab device for exclusive use.
- - \e RTAUDIO_SCHEDULE_REALTIME: Attempt to select realtime scheduling for callback thread.
- - \e RTAUDIO_ALSA_USE_DEFAULT: Use the "default" PCM device (ALSA only).
-
- By default, RtAudio streams pass and receive audio data from the
- client in an interleaved format. By passing the
- RTAUDIO_NONINTERLEAVED flag to the openStream() function, audio
- data will instead be presented in non-interleaved buffers. In
- this case, each buffer argument in the RtAudioCallback function
- will point to a single array of data, with \c nFrames samples for
- each channel concatenated back-to-back. For example, the first
- sample of data for the second channel would be located at index \c
- nFrames (assuming the \c buffer pointer was recast to the correct
- data type for the stream).
-
- Certain audio APIs offer a number of parameters that influence the
- I/O latency of a stream. By default, RtAudio will attempt to set
- these parameters internally for robust (glitch-free) performance
- (though some APIs, like Windows Direct Sound, make this difficult).
- By passing the RTAUDIO_MINIMIZE_LATENCY flag to the openStream()
- function, internal stream settings will be influenced in an attempt
- to minimize stream latency, though possibly at the expense of stream
- performance.
-
- If the RTAUDIO_HOG_DEVICE flag is set, RtAudio will attempt to
- open the input and/or output stream device(s) for exclusive use.
- Note that this is not possible with all supported audio APIs.
-
- If the RTAUDIO_SCHEDULE_REALTIME flag is set, RtAudio will attempt
- to select realtime scheduling (round-robin) for the callback thread.
- The \c priority parameter will only be used if the RTAUDIO_SCHEDULE_REALTIME
- flag is set. It defines the thread's realtime priority.
-
- If the RTAUDIO_ALSA_USE_DEFAULT flag is set, RtAudio will attempt to
- open the "default" PCM device when using the ALSA API. Note that this
- will override any specified input or output device id.
-
- The \c numberOfBuffers parameter can be used to control stream
- latency in the Windows DirectSound, Linux OSS, and Linux Alsa APIs
- only. A value of two is usually the smallest allowed. Larger
- numbers can potentially result in more robust stream performance,
- though likely at the cost of stream latency. The value set by the
- user is replaced during execution of the RtAudio::openStream()
- function by the value actually used by the system.
-
- The \c streamName parameter can be used to set the client name
- when using the Jack API. By default, the client name is set to
- RtApiJack. However, if you wish to create multiple instances of
- RtAudio with Jack, each instance must have a unique client name.
- */
- struct StreamOptions {
- RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */
- unsigned int numberOfBuffers; /*!< Number of stream buffers. */
- std::string streamName; /*!< A stream name (currently used only in Jack). */
- int priority; /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */
-
- // Default constructor.
- StreamOptions()
- : flags(0), numberOfBuffers(0), priority(0) {}
- };
-
- //! A static function to determine the available compiled audio APIs.
- /*!
- The values returned in the std::vector can be compared against
- the enumerated list values. Note that there can be more than one
- API compiled for certain operating systems.
- */
- static void getCompiledApi( std::vector &apis ) throw();
-
- //! The class constructor.
- /*!
- The constructor performs minor initialization tasks. No exceptions
- can be thrown.
-
- If no API argument is specified and multiple API support has been
- compiled, the default order of use is JACK, ALSA, OSS (Linux
- systems) and ASIO, DS (Windows systems).
- */
- RtAudio( RtAudio::Api api=UNSPECIFIED ) throw();
-
- //! The destructor.
- /*!
- If a stream is running or open, it will be stopped and closed
- automatically.
- */
- ~RtAudio() throw();
-
- //! Returns the audio API specifier for the current instance of RtAudio.
- RtAudio::Api getCurrentApi( void ) throw();
-
- //! A public function that queries for the number of audio devices available.
- /*!
- This function performs a system query of available devices each time it
- is called, thus supporting devices connected \e after instantiation. If
- a system error occurs during processing, a warning will be issued.
- */
- unsigned int getDeviceCount( void ) throw();
-
- //! Return an RtAudio::DeviceInfo structure for a specified device number.
- /*!
-
- Any device integer between 0 and getDeviceCount() - 1 is valid.
- If an invalid argument is provided, an RtError (type = INVALID_USE)
- will be thrown. If a device is busy or otherwise unavailable, the
- structure member "probed" will have a value of "false" and all
- other members are undefined. If the specified device is the
- current default input or output device, the corresponding
- "isDefault" member will have a value of "true".
- */
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
-
- //! A function that returns the index of the default output device.
- /*!
- If the underlying audio API does not provide a "default
- device", or if no devices are available, the return value will be
- 0. Note that this is a valid device identifier and it is the
- client's responsibility to verify that a device is available
- before attempting to open a stream.
- */
- unsigned int getDefaultOutputDevice( void ) throw();
-
- //! A function that returns the index of the default input device.
- /*!
- If the underlying audio API does not provide a "default
- device", or if no devices are available, the return value will be
- 0. Note that this is a valid device identifier and it is the
- client's responsibility to verify that a device is available
- before attempting to open a stream.
- */
- unsigned int getDefaultInputDevice( void ) throw();
-
- //! A public function for opening a stream with the specified parameters.
- /*!
- An RtError (type = SYSTEM_ERROR) is thrown if a stream cannot be
- opened with the specified parameters or an error occurs during
- processing. An RtError (type = INVALID_USE) is thrown if any
- invalid device ID or channel number parameters are specified.
-
- \param outputParameters Specifies output stream parameters to use
- when opening a stream, including a device ID, number of channels,
- and starting channel number. For input-only streams, this
- argument should be NULL. The device ID is an index value between
- 0 and getDeviceCount() - 1.
- \param inputParameters Specifies input stream parameters to use
- when opening a stream, including a device ID, number of channels,
- and starting channel number. For output-only streams, this
- argument should be NULL. The device ID is an index value between
- 0 and getDeviceCount() - 1.
- \param format An RtAudioFormat specifying the desired sample data format.
- \param sampleRate The desired sample rate (sample frames per second).
- \param *bufferFrames A pointer to a value indicating the desired
- internal buffer size in sample frames. The actual value
- used by the device is returned via the same pointer. A
- value of zero can be specified, in which case the lowest
- allowable value is determined.
- \param callback A client-defined function that will be invoked
- when input data is available and/or output data is needed.
- \param userData An optional pointer to data that can be accessed
- from within the callback function.
- \param options An optional pointer to a structure containing various
- global stream options, including a list of OR'ed RtAudioStreamFlags
- and a suggested number of stream buffers that can be used to
- control stream latency. More buffers typically result in more
- robust performance, though at a cost of greater latency. If a
- value of zero is specified, a system-specific median value is
- chosen. If the RTAUDIO_MINIMIZE_LATENCY flag bit is set, the
- lowest allowable value is used. The actual value used is
- returned via the structure argument. The parameter is API dependent.
- */
- void openStream( RtAudio::StreamParameters *outputParameters,
- RtAudio::StreamParameters *inputParameters,
- RtAudioFormat format, unsigned int sampleRate,
- unsigned int *bufferFrames, RtAudioCallback callback,
- void *userData = NULL, RtAudio::StreamOptions *options = NULL );
-
- //! A function that closes a stream and frees any associated stream memory.
- /*!
- If a stream is not open, this function issues a warning and
- returns (no exception is thrown).
- */
- void closeStream( void ) throw();
-
- //! A function that starts a stream.
- /*!
- An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
- during processing. An RtError (type = INVALID_USE) is thrown if a
- stream is not open. A warning is issued if the stream is already
- running.
- */
- void startStream( void );
-
- //! Stop a stream, allowing any samples remaining in the output queue to be played.
- /*!
- An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
- during processing. An RtError (type = INVALID_USE) is thrown if a
- stream is not open. A warning is issued if the stream is already
- stopped.
- */
- void stopStream( void );
-
- //! Stop a stream, discarding any samples remaining in the input/output queue.
- /*!
- An RtError (type = SYSTEM_ERROR) is thrown if an error occurs
- during processing. An RtError (type = INVALID_USE) is thrown if a
- stream is not open. A warning is issued if the stream is already
- stopped.
- */
- void abortStream( void );
-
- //! Returns true if a stream is open and false if not.
- bool isStreamOpen( void ) const throw();
-
- //! Returns true if the stream is running and false if it is stopped or not open.
- bool isStreamRunning( void ) const throw();
-
- //! Returns the number of elapsed seconds since the stream was started.
- /*!
- If a stream is not open, an RtError (type = INVALID_USE) will be thrown.
- */
- double getStreamTime( void );
-
- //! Returns the internal stream latency in sample frames.
- /*!
- The stream latency refers to delay in audio input and/or output
- caused by internal buffering by the audio system and/or hardware.
- For duplex streams, the returned value will represent the sum of
- the input and output latencies. If a stream is not open, an
- RtError (type = INVALID_USE) will be thrown. If the API does not
- report latency, the return value will be zero.
- */
- long getStreamLatency( void );
-
- //! Returns actual sample rate in use by the stream.
- /*!
- On some systems, the sample rate used may be slightly different
- than that specified in the stream parameters. If a stream is not
- open, an RtError (type = INVALID_USE) will be thrown.
- */
- unsigned int getStreamSampleRate( void );
-
- //! Specify whether warning messages should be printed to stderr.
- void showWarnings( bool value = true ) throw();
-
- protected:
-
- void openRtApi( RtAudio::Api api );
- RtApi *rtapi_;
-};
-
-// Operating system dependent thread functionality.
-#if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
- #include
- #include
-
- typedef unsigned long ThreadHandle;
- typedef CRITICAL_SECTION StreamMutex;
-
-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
- // Using pthread library for various flavors of unix.
- #include
-
- typedef pthread_t ThreadHandle;
- typedef pthread_mutex_t StreamMutex;
-
-#else // Setup for "dummy" behavior
-
- #define __RTAUDIO_DUMMY__
- typedef int ThreadHandle;
- typedef int StreamMutex;
-
-#endif
-
-// This global structure type is used to pass callback information
-// between the private RtAudio stream structure and global callback
-// handling functions.
-struct CallbackInfo {
- void *object; // Used as a "this" pointer.
- ThreadHandle thread;
- void *callback;
- void *userData;
- void *apiInfo; // void pointer for API specific callback information
- bool isRunning;
-
- // Default constructor.
- CallbackInfo()
- :object(0), callback(0), userData(0), apiInfo(0), isRunning(false) {}
-};
-
-// **************************************************************** //
-//
-// RtApi class declaration.
-//
-// Subclasses of RtApi contain all API- and OS-specific code necessary
-// to fully implement the RtAudio API.
-//
-// Note that RtApi is an abstract base class and cannot be
-// explicitly instantiated. The class RtAudio will create an
-// instance of an RtApi subclass (RtApiOss, RtApiAlsa,
-// RtApiJack, RtApiCore, RtApiDs, or RtApiAsio).
-//
-// **************************************************************** //
-
-#if defined( HAVE_GETTIMEOFDAY )
- #include
-#endif
-
-#include
-
-class RtApi
-{
-public:
-
- RtApi();
- virtual ~RtApi();
- virtual RtAudio::Api getCurrentApi( void ) = 0;
- virtual unsigned int getDeviceCount( void ) = 0;
- virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0;
- virtual unsigned int getDefaultInputDevice( void );
- virtual unsigned int getDefaultOutputDevice( void );
- void openStream( RtAudio::StreamParameters *outputParameters,
- RtAudio::StreamParameters *inputParameters,
- RtAudioFormat format, unsigned int sampleRate,
- unsigned int *bufferFrames, RtAudioCallback callback,
- void *userData, RtAudio::StreamOptions *options );
- virtual void closeStream( void );
- virtual void startStream( void ) = 0;
- virtual void stopStream( void ) = 0;
- virtual void abortStream( void ) = 0;
- long getStreamLatency( void );
- unsigned int getStreamSampleRate( void );
- virtual double getStreamTime( void );
- bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; };
- bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; };
- void showWarnings( bool value ) { showWarnings_ = value; };
-
-
-protected:
-
- static const unsigned int MAX_SAMPLE_RATES;
- static const unsigned int SAMPLE_RATES[];
-
- enum { FAILURE, SUCCESS };
-
- enum StreamState {
- STREAM_STOPPED,
- STREAM_STOPPING,
- STREAM_RUNNING,
- STREAM_CLOSED = -50
- };
-
- enum StreamMode {
- OUTPUT,
- INPUT,
- DUPLEX,
- UNINITIALIZED = -75
- };
-
- // A protected structure used for buffer conversion.
- struct ConvertInfo {
- int channels;
- int inJump, outJump;
- RtAudioFormat inFormat, outFormat;
- std::vector inOffset;
- std::vector outOffset;
- };
-
- // A protected structure for audio streams.
- struct RtApiStream {
- unsigned int device[2]; // Playback and record, respectively.
- void *apiHandle; // void pointer for API specific stream handle information
- StreamMode mode; // OUTPUT, INPUT, or DUPLEX.
- StreamState state; // STOPPED, RUNNING, or CLOSED
- char *userBuffer[2]; // Playback and record, respectively.
- char *deviceBuffer;
- bool doConvertBuffer[2]; // Playback and record, respectively.
- bool userInterleaved;
- bool deviceInterleaved[2]; // Playback and record, respectively.
- bool doByteSwap[2]; // Playback and record, respectively.
- unsigned int sampleRate;
- unsigned int bufferSize;
- unsigned int nBuffers;
- unsigned int nUserChannels[2]; // Playback and record, respectively.
- unsigned int nDeviceChannels[2]; // Playback and record channels, respectively.
- unsigned int channelOffset[2]; // Playback and record, respectively.
- unsigned long latency[2]; // Playback and record, respectively.
- RtAudioFormat userFormat;
- RtAudioFormat deviceFormat[2]; // Playback and record, respectively.
- StreamMutex mutex;
- CallbackInfo callbackInfo;
- ConvertInfo convertInfo[2];
- double streamTime; // Number of elapsed seconds since the stream started.
-
-#if defined(HAVE_GETTIMEOFDAY)
- struct timeval lastTickTimestamp;
-#endif
-
- RtApiStream()
- :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; }
- };
-
- typedef signed short Int16;
- typedef signed int Int32;
- typedef float Float32;
- typedef double Float64;
-
- std::ostringstream errorStream_;
- std::string errorText_;
- bool showWarnings_;
- RtApiStream stream_;
-
- /*!
- Protected, api-specific method that attempts to open a device
- with the given parameters. This function MUST be implemented by
- all subclasses. If an error is encountered during the probe, a
- "warning" message is reported and FAILURE is returned. A
- successful probe is indicated by a return value of SUCCESS.
- */
- virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-
- //! A protected function used to increment the stream time.
- void tickStreamTime( void );
-
- //! Protected common method to clear an RtApiStream structure.
- void clearStreamInfo();
-
- /*!
- Protected common method that throws an RtError (type =
- INVALID_USE) if a stream is not open.
- */
- void verifyStream( void );
-
- //! Protected common error method to allow global control over error handling.
- void error( RtError::Type type );
-
- /*!
- Protected method used to perform format, channel number, and/or interleaving
- conversions between the user and device buffers.
- */
- void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info );
-
- //! Protected common method used to perform byte-swapping on buffers.
- void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format );
-
- //! Protected common method that returns the number of bytes for a given format.
- unsigned int formatBytes( RtAudioFormat format );
-
- //! Protected common method that sets up the parameters for buffer conversion.
- void setConvertInfo( StreamMode mode, unsigned int firstChannel );
-};
-
-// **************************************************************** //
-//
-// Inline RtAudio definitions.
-//
-// **************************************************************** //
-
-inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); }
-inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); }
-inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); }
-inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); }
-inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); }
-inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); }
-inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); }
-inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); }
-inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); }
-inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); }
-inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); }
-inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); }
-inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); };
-inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); }
-inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); }
-
-// RtApi Subclass prototypes.
-
-#if defined(__MACOSX_CORE__)
-
-#include
-
-class RtApiCore: public RtApi
-{
-public:
-
- RtApiCore();
- ~RtApiCore();
- RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- unsigned int getDefaultOutputDevice( void );
- unsigned int getDefaultInputDevice( void );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
- long getStreamLatency( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- bool callbackEvent( AudioDeviceID deviceId,
- const AudioBufferList *inBufferList,
- const AudioBufferList *outBufferList );
-
- private:
-
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
- static const char* getErrorCode( OSStatus code );
-};
-
-#endif
-
-#if defined(__UNIX_JACK__)
-
-class RtApiJack: public RtApi
-{
-public:
-
- RtApiJack();
- ~RtApiJack();
- RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
- long getStreamLatency( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- bool callbackEvent( unsigned long nframes );
-
- private:
-
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__WINDOWS_ASIO__)
-
-class RtApiAsio: public RtApi
-{
-public:
-
- RtApiAsio();
- ~RtApiAsio();
- RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
- long getStreamLatency( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- bool callbackEvent( long bufferIndex );
-
- private:
-
- std::vector devices_;
- void saveDeviceInfo( void );
- bool coInitialized_;
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__WINDOWS_DS__)
-
-class RtApiDs: public RtApi
-{
-public:
-
- RtApiDs();
- ~RtApiDs();
- RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; };
- unsigned int getDeviceCount( void );
- unsigned int getDefaultOutputDevice( void );
- unsigned int getDefaultInputDevice( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
- long getStreamLatency( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- void callbackEvent( void );
-
- private:
-
- bool coInitialized_;
- bool buffersRolling;
- long duplexPrerollBytes;
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__LINUX_ALSA__)
-
-class RtApiAlsa: public RtApi
-{
-public:
-
- RtApiAlsa();
- ~RtApiAlsa();
- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- void callbackEvent( void );
-
- private:
-
- std::vector devices_;
- void saveDeviceInfo( void );
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__LINUX_PULSE__)
-
-class RtApiPulse: public RtApi
-{
-public:
- ~RtApiPulse();
- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- void callbackEvent( void );
-
- private:
-
- std::vector devices_;
- void saveDeviceInfo( void );
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__LINUX_OSS__)
-
-class RtApiOss: public RtApi
-{
-public:
-
- RtApiOss();
- ~RtApiOss();
- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; };
- unsigned int getDeviceCount( void );
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device );
- void closeStream( void );
- void startStream( void );
- void stopStream( void );
- void abortStream( void );
-
- // This function is intended for internal use only. It must be
- // public because it is called by the internal callback handler,
- // which is not a member of RtAudio. External use of this function
- // will most likely produce highly undesireable results!
- void callbackEvent( void );
-
- private:
-
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options );
-};
-
-#endif
-
-#if defined(__RTAUDIO_DUMMY__)
-
-class RtApiDummy: public RtApi
-{
-public:
-
- RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtError::WARNING ); };
- RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; };
- unsigned int getDeviceCount( void ) { return 0; };
- RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) { RtAudio::DeviceInfo info; return info; };
- void closeStream( void ) {};
- void startStream( void ) {};
- void stopStream( void ) {};
- void abortStream( void ) {};
-
- private:
-
- bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
- unsigned int firstChannel, unsigned int sampleRate,
- RtAudioFormat format, unsigned int *bufferSize,
- RtAudio::StreamOptions *options ) { return false; };
-};
-
-#endif
-
-#endif
-
-// Indentation settings for Vim and Emacs
-//
-// Local Variables:
-// c-basic-offset: 2
-// indent-tabs-mode: nil
-// End:
-//
-// vim: et sts=2 sw=2
diff --git a/c++/carla-engine/rtaudio-4.0.11/RtError.h b/c++/carla-engine/rtaudio-4.0.11/RtError.h
deleted file mode 100644
index a64f434..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/RtError.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/************************************************************************/
-/*! \class RtError
- \brief Exception handling class for RtAudio & RtMidi.
-
- The RtError class is quite simple but it does allow errors to be
- "caught" by RtError::Type. See the RtAudio and RtMidi
- documentation to know which methods can throw an RtError.
-
-*/
-/************************************************************************/
-
-#ifndef RTERROR_H
-#define RTERROR_H
-
-#include
-#include
-#include
-
-class RtError : public std::exception
-{
- public:
- //! Defined RtError types.
- enum Type {
- WARNING, /*!< A non-critical error. */
- DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */
- UNSPECIFIED, /*!< The default, unspecified error type. */
- NO_DEVICES_FOUND, /*!< No devices found on system. */
- INVALID_DEVICE, /*!< An invalid device ID was specified. */
- MEMORY_ERROR, /*!< An error occured during memory allocation. */
- INVALID_PARAMETER, /*!< An invalid parameter was specified to a function. */
- INVALID_USE, /*!< The function was called incorrectly. */
- DRIVER_ERROR, /*!< A system driver error occured. */
- SYSTEM_ERROR, /*!< A system error occured. */
- THREAD_ERROR /*!< A thread error occured. */
- };
-
- //! The constructor.
- RtError( const std::string& message, Type type = RtError::UNSPECIFIED ) throw() : message_(message), type_(type) {}
-
- //! The destructor.
- virtual ~RtError( void ) throw() {}
-
- //! Prints thrown error message to stderr.
- virtual void printMessage( void ) const throw() { std::cerr << '\n' << message_ << "\n\n"; }
-
- //! Returns the thrown error message type.
- virtual const Type& getType(void) const throw() { return type_; }
-
- //! Returns the thrown error message string.
- virtual const std::string& getMessage(void) const throw() { return message_; }
-
- //! Returns the thrown error message as a c-style string.
- virtual const char* what( void ) const throw() { return message_.c_str(); }
-
- protected:
- std::string message_;
- Type type_;
-};
-
-#endif
diff --git a/c++/carla-engine/rtaudio-4.0.11/config/config.guess b/c++/carla-engine/rtaudio-4.0.11/config/config.guess
deleted file mode 100644
index 313be34..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/config/config.guess
+++ /dev/null
@@ -1,1371 +0,0 @@
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-
-timestamp='2004-02-26'
-
-# This file 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
-# (at your option) 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Written by Per Bothner .
-# Please send patches to .
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to ."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script.
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int dummy(){}" > $dummy.c
- for c in cc gcc c89 ; do
- ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1
- if test $? = 0 ; then
- CC_FOR_BUILD="$c"; break
- fi
- done
- rm -f $dummy.c $dummy.o $dummy.rel
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 8/24/94.)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # Netbsd (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- # Determine the machine/vendor (is the vendor relevant).
- case "${UNAME_MACHINE}" in
- amiga) machine=m68k-unknown ;;
- arm32) machine=arm-unknown ;;
- atari*) machine=m68k-atari ;;
- sun3*) machine=m68k-sun ;;
- mac68k) machine=m68k-apple ;;
- macppc) machine=powerpc-apple ;;
- hp3[0-9][05]) machine=m68k-hp ;;
- ibmrt|romp-ibm) machine=romp-ibm ;;
- *) machine=${UNAME_MACHINE}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE}" in
- i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit 0 ;;
- alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- cat <$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- case `./$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- esac
- fi
- rm -f $dummy.s $dummy
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit 0 ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit 0 ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit 0 ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit 0;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit 0 ;;
- arc64:OpenBSD:*:*)
- echo mips64el-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hkmips:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit 0 ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit 0 ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit 0 ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- i86pc:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit 0 ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
- atari*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit 0 ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit 0 ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit 0 ;;
- sun3*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit 0 ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy \
- && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit 0 ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit 0 ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit 0 ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit 0 ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit 0 ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit 0 ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit 0 ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit 0 ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit 0 ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit 0 ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit 0 ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- sed 's/^ //' << EOF >$dummy.c
- #include
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo rs6000-ibm-aix3.2.5
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit 0 ;;
- *:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit 0 ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit 0 ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit 0 ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit 0 ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit 0 ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit 0 ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- case "${HPUX_REV}" in
- 11.[0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- esac ;;
- esac
- fi ;;
- esac
- if [ "${HP_ARCH}" = "" ]; then
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include
- #include
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
- if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
- rm -f $dummy.c $dummy
- fi ;;
- esac
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit 0 ;;
- 3050*:HI-UX:*:*)
- sed 's/^ //' << EOF >$dummy.c
- #include
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo unknown-hitachi-hiuxwe2
- exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit 0 ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit 0 ;;
- *9??*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit 0 ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit 0 ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit 0 ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit 0 ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit 0 ;;
- hppa*:OpenBSD:*:*)
- echo hppa-unknown-openbsd
- exit 0 ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit 0 ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit 0 ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit 0 ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:*:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE}
- exit 0 ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
- exit 0 ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3D:*:*:*)
- echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY-2:*:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
- *:FreeBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit 0 ;;
- i*:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit 0 ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit 0 ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i386-pc-interix
- exit 0 ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit 0 ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit 0 ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
- *:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit 0 ;;
- arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
- exit 0 ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- mips:Linux:*:*)
- cat >$dummy.c < /* for printf() prototype */
-int main (int argc, char *argv[]) {
-#else
-int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __MIPSEB__
- printf ("%s-unknown-linux-gnu\n", argv[1]);
-#endif
-#ifdef __MIPSEL__
- printf ("%sel-unknown-linux-gnu\n", argv[1]);
-#endif
- return 0;
-}
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- ;;
- ppc:Linux:*:*)
- # Determine Lib Version
- cat >$dummy.c <
-#if defined(__GLIBC__)
-extern char __libc_version[];
-extern char __libc_release[];
-#endif
-main(argc, argv)
- int argc;
- char *argv[];
-{
-#if defined(__GLIBC__)
- printf("%s %s\n", __libc_version, __libc_release);
-#else
- printf("unknown\n");
-#endif
- return 0;
-}
-EOF
- LIBC=""
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- ./$dummy | grep 1\.99 > /dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; fi
- fi
- rm -f $dummy.c $dummy
- echo powerpc-unknown-linux-gnu${LIBC}
- exit 0 ;;
- alpha:Linux:*:*)
- cat <$dummy.s
- .data
- \$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
- .text
- .globl main
- .align 4
- .ent main
- main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- LIBC=""
- $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- case `./$dummy` in
- 0-0) UNAME_MACHINE="alpha" ;;
- 1-0) UNAME_MACHINE="alphaev5" ;;
- 1-1) UNAME_MACHINE="alphaev56" ;;
- 1-101) UNAME_MACHINE="alphapca56" ;;
- 2-303) UNAME_MACHINE="alphaev6" ;;
- 2-307) UNAME_MACHINE="alphaev67" ;;
- esac
- objdump --private-headers $dummy | \
- grep ld.so.1 > /dev/null
- if test "$?" = 0 ; then
- LIBC="libc1"
- fi
- fi
- rm -f $dummy.s $dummy
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit 0 ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit 0 ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit 0 ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit 0 ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit 0 ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- ld_supported_emulations=`cd /; ld --help 2>&1 \
- | sed -ne '/supported emulations:/!d
- s/[ ][ ]*/ /g
- s/.*supported emulations: *//
- s/ .*//
- p'`
- case "$ld_supported_emulations" in
- i*86linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0
- ;;
- elf_i*86)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- i*86coff)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit 0
- ;;
- esac
- # Either a pre-BFD a.out linker (linux-gnuoldld)
- # or one that does not give us useful --help.
- # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
- # If ld does not provide *any* "supported emulations:"
- # that means it is gnuoldld.
- test -z "$ld_supported_emulations" && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
- case "${UNAME_MACHINE}" in
- i*86)
- VENDOR=pc;
- ;;
- *)
- VENDOR=unknown;
- ;;
- esac
- # Determine whether the default compiler is a.out or elf
- cat >$dummy.c <
-#ifdef __cplusplus
-#include /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-# if __GLIBC__ >= 2
- printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
-# else
- printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-# endif
-# else
- printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
-# endif
-#else
- printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
-#endif
- return 0;
-}
-EOF
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
- ;;
-# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
-# are messed up and put the nodename in both sysname and nodename.
- i*86:DYNIX/ptx:4*:*)
- echo i386-sequent-sysv4
- exit 0 ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit 0 ;;
- i*86:*:5:7*)
- # Fixed at (any) Pentium or better
- UNAME_MACHINE=i586
- if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
- echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit 0 ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit 0 ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit 0 ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit 0 ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit 0 ;;
- M68*:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit 0 ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit 0 ;;
- PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says
- echo i586-unisys-sysv4
- exit 0 ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes .
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit 0 ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit 0 ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit 0 ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit 0 ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit 0 ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit 0 ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit 0 ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit 0 ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
- *:Darwin:*:*)
- echo `uname -p`-apple-darwin${UNAME_RELEASE}
- exit 0 ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- if test "${UNAME_MACHINE}" = "x86pc"; then
- UNAME_MACHINE=pc
- fi
- echo `uname -p`-${UNAME_MACHINE}-nto-qnx
- exit 0 ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit 0 ;;
- NSR-[KW]:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit 0 ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit 0 ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit 0 ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit 0 ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit 0 ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit 0 ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit 0 ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit 0 ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit 0 ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit 0 ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-cat >$dummy.c <
-# include
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit 0 ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit 0 ;;
- c34*)
- echo c34-convex-bsd
- exit 0 ;;
- c38*)
- echo c38-convex-bsd
- exit 0 ;;
- c4*)
- echo c4-convex-bsd
- exit 0 ;;
- esac
-fi
-
-cat >&2 < in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/c++/carla-engine/rtaudio-4.0.11/config/config.sub b/c++/carla-engine/rtaudio-4.0.11/config/config.sub
deleted file mode 100755
index 7d3f49f..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/config/config.sub
+++ /dev/null
@@ -1,1362 +0,0 @@
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
-
-timestamp='2004-02-26'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file 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
-# (at your option) 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.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# Please send patches to .
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to ."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
- --version | -v )
- echo "$version" ; exit 0 ;;
- --help | --h* | -h )
- echo "$usage"; exit 0 ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit 0;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis)
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
- | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
- | pyramid | mn10200 | mn10300 | tron | a29k \
- | 580 | i960 | h8300 \
- | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
- | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
- | hppa64 \
- | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
- | alphaev6[78] \
- | we32k | ns16k | clipper | i370 | sh | sh[34] \
- | powerpc | powerpcle \
- | 1750a | dsp16xx | pdp10 | pdp11 \
- | mips16 | mips64 | mipsel | mips64el \
- | mips64orion | mips64orionel | mipstx39 | mipstx39el \
- | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
- | mips64vr5000 | miprs64vr5000el | mcore | s390 | s390x \
- | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
- | v850 | c4x \
- | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
- | pj | pjl | h8500)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | w65)
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- # FIXME: clean up the formatting here.
- vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
- | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
- | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
- | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
- | xmp-* | ymp-* \
- | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
- | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
- | hppa2.0n-* | hppa64-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
- | alphaev6[78]-* \
- | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
- | clipper-* | orion-* \
- | sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
- | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
- | mips16-* | mips64-* | mipsel-* \
- | mips64el-* | mips64orion-* | mips64orionel-* \
- | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
- | mipstx39-* | mipstx39el-* | mcore-* \
- | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
- | [cjt]90-* \
- | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
- | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
- | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
- os=-unicos
- ;;
- [cjt]90)
- basic_machine=${basic_machine}-cray
- os=-unicos
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux-gnu
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux-gnu
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- mmix*)
- basic_machine=mmix-knuth
- os=-mmixware
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pentium | p5 | k5 | k6 | nexgen)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2)
- basic_machine=i686-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sparclite-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=t3e-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xmp)
- basic_machine=xmp-cray
- os=-unicos
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- mips)
- if [ x$os = x-linux-gnu ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh3 | sh4)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv9 | sparcv9b)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- c4x*)
- basic_machine=c4x-none
- os=-coff
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto*)
- os=-nto-qnx
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-ibm)
- os=-aix
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -vxsim* | -vxworks*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
diff --git a/c++/carla-engine/rtaudio-4.0.11/config/install.sh b/c++/carla-engine/rtaudio-4.0.11/config/install.sh
deleted file mode 100755
index e69de29..0000000
diff --git a/c++/carla-engine/rtaudio-4.0.11/configure b/c++/carla-engine/rtaudio-4.0.11/configure
deleted file mode 100755
index b71e561..0000000
--- a/c++/carla-engine/rtaudio-4.0.11/configure
+++ /dev/null
@@ -1,6580 +0,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for RtAudio 4.0.
-#
-# Report bugs to .
-#
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be more Bourne compatible
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-as_nl='
-'
-export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
- as_echo='printf %s\n'
- as_echo_n='printf %s'
-else
- if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
- as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
- as_echo_n='/usr/ucb/echo -n'
- else
- as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
- as_echo_n_body='eval
- arg=$1;
- case $arg in
- *"$as_nl"*)
- expr "X$arg" : "X\\(.*\\)$as_nl";
- arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
- esac;
- expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
- '
- export as_echo_n_body
- as_echo_n='sh -c $as_echo_n_body as_echo'
- fi
- export as_echo_body
- as_echo='sh -c $as_echo_body as_echo'
-fi
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
-fi
-
-
-# IFS
-# We need space, tab and new line, in precisely that order. Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" "" $as_nl"
-
-# Find who we are. Look in the path if we contain no directory separator.
-case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-IFS=$as_save_IFS
-
- ;;
-esac
-# We did not find ourselves, most probably we were run as `sh COMMAND'
-# in which case we are not to be found in the path.
-if test "x$as_myself" = x; then
- as_myself=$0
-fi
-if test ! -f "$as_myself"; then
- $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
- { (exit 1); exit 1; }
-fi
-
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
- as_basename=basename
-else
- as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{
- s//\1/
- q
- }
- /^X\/\(\/\/\)$/{
- s//\1/
- q
- }
- /^X\/\(\/\).*/{
- s//\1/
- q
- }
- s/.*/./; q'`
-
-# CDPATH.
-$as_unset CDPATH
-
-
-if test "x$CONFIG_SHELL" = x; then
- if (eval ":") 2>/dev/null; then
- as_have_required=yes
-else
- as_have_required=no
-fi
-
- if test $as_have_required = yes && (eval ":
-(as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=\$LINENO
- as_lineno_2=\$LINENO
- test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
- test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
- :
-else
- as_candidate_shells=
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- case $as_dir in
- /*)
- for as_base in sh bash ksh sh5; do
- as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
- done;;
- esac
-done
-IFS=$as_save_IFS
-
-
- for as_shell in $as_candidate_shells $SHELL; do
- # Try only shells that exist, to save several forks.
- if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
- { ("$as_shell") 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-:
-_ASEOF
-}; then
- CONFIG_SHELL=$as_shell
- as_have_required=yes
- if { "$as_shell" 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in
- *posix*) set -o posix ;;
-esac
-
-fi
-
-
-:
-(as_func_return () {
- (exit $1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
- break
-fi
-
-fi
-
- done
-
- if test "x$CONFIG_SHELL" != x; then
- for as_var in BASH_ENV ENV
- do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
- done
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
-
-
- if test $as_have_required = no; then
- echo This script requires a shell more modern than all the
- echo shells that I found on your system. Please install a
- echo modern shell, or manually run the script under such a
- echo shell if you do have one.
- { (exit 1); exit 1; }
-fi
-
-
-fi
-
-fi
-
-
-
-(eval "as_func_return () {
- (exit \$1)
-}
-as_func_success () {
- as_func_return 0
-}
-as_func_failure () {
- as_func_return 1
-}
-as_func_ret_success () {
- return 0
-}
-as_func_ret_failure () {
- return 1
-}
-
-exitcode=0
-if as_func_success; then
- :
-else
- exitcode=1
- echo as_func_success failed.
-fi
-
-if as_func_failure; then
- exitcode=1
- echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
- :
-else
- exitcode=1
- echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
- exitcode=1
- echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
- :
-else
- exitcode=1
- echo positional parameters were not saved.
-fi
-
-test \$exitcode = 0") || {
- echo No shell found that supports shell functions.
- echo Please tell bug-autoconf@gnu.org about your system,
- echo including any error possibly output before this message.
- echo This can help us improve future autoconf versions.
- echo Configuration will now proceed without shell functions.
-}
-
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line after each line using $LINENO; the second 'sed'
- # does the real work. The second script uses 'N' to pair each
- # line-number line with the line containing $LINENO, and appends
- # trailing '-' during substitution so that $LINENO is not a special
- # case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # scripts with optimization help from Paolo Bonzini. Blame Lee
- # E. McMahon (1931-1989) for sed's syntax. :-)
- sed -n '
- p
- /[$]LINENO/=
- ' <$as_myself |
- sed '
- s/[$]LINENO.*/&-/
- t lineno
- b
- :lineno
- N
- :loop
- s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
- t loop
- s/-\n.*//
- ' >$as_me.lineno &&
- chmod +x "$as_me.lineno" ||
- { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensitive to this).
- . "./$as_me.lineno"
- # Exit status is that of the last command.
- exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
- as_dirname=dirname
-else
- as_dirname=false
-fi
-
-ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
--n*)
- case `echo 'x\c'` in
- *c*) ECHO_T=' ';; # ECHO_T is single tab character.
- *) ECHO_C='\c';;
- esac;;
-*)
- ECHO_N='-n';;
-esac
-if expr a : '\(a\)' >/dev/null 2>&1 &&
- test "X`expr 00001 : '.*\(...\)'`" = X001; then
- as_expr=expr
-else
- as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-if test -d conf$$.dir; then
- rm -f conf$$.dir/conf$$.file
-else
- rm -f conf$$.dir
- mkdir conf$$.dir 2>/dev/null
-fi
-if (echo >conf$$.file) 2>/dev/null; then
- if ln -s conf$$.file conf$$ 2>/dev/null; then
- as_ln_s='ln -s'
- # ... but there are two gotchas:
- # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
- # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -p'.
- ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -p'
- elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
- else
- as_ln_s='cp -p'
- fi
-else
- as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
-rmdir conf$$.dir 2>/dev/null
-
-if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
-else
- test -d ./-p && rmdir ./-p
- as_mkdir_p=false
-fi
-
-if test -x / >/dev/null 2>&1; then
- as_test_x='test -x'
-else
- if ls -dL / >/dev/null 2>&1; then
- as_ls_L_option=L
- else
- as_ls_L_option=
- fi
- as_test_x='
- eval sh -c '\''
- if test -d "$1"; then
- test -d "$1/.";
- else
- case $1 in
- -*)set "./$1";;
- esac;
- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
- ???[sx]*):;;*)false;;esac;fi
- '\'' sh
- '
-fi
-as_executable_p=$as_test_x
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-
-exec 7<&0 &1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME='RtAudio'
-PACKAGE_TARNAME='rtaudio'
-PACKAGE_VERSION='4.0'
-PACKAGE_STRING='RtAudio 4.0'
-PACKAGE_BUGREPORT='gary@music.mcgill.ca'
-
-ac_unique_file="RtAudio.cpp"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include
-#ifdef HAVE_SYS_TYPES_H
-# include
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include
-#endif
-#ifdef STDC_HEADERS
-# include
-# include
-#else
-# ifdef HAVE_STDLIB_H
-# include
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include
-# endif
-# include
-#endif
-#ifdef HAVE_STRINGS_H
-# include