| @@ -108,6 +108,7 @@ data/windows/Carla-*-win64/ | |||||
| source/bridges/jackplugin/libjack.so.0 | source/bridges/jackplugin/libjack.so.0 | ||||
| source/frontend/Makefile | source/frontend/Makefile | ||||
| source/tests/ansi-pedantic-test_* | source/tests/ansi-pedantic-test_* | ||||
| source/tests/CachedPlugins | |||||
| source/tests/CarlaRingBuffer | source/tests/CarlaRingBuffer | ||||
| source/tests/CarlaPipeUtils | source/tests/CarlaPipeUtils | ||||
| source/tests/CarlaString | source/tests/CarlaString | ||||
| @@ -25,7 +25,9 @@ | |||||
| #include "CarlaThread.hpp" | #include "CarlaThread.hpp" | ||||
| #include "LinkedList.hpp" | #include "LinkedList.hpp" | ||||
| #include "juce_audio_formats/juce_audio_formats.h" | |||||
| #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| # include "juce_audio_formats/juce_audio_formats.h" | |||||
| #endif | |||||
| #ifdef CARLA_OS_MAC | #ifdef CARLA_OS_MAC | ||||
| # include "juce_audio_processors/juce_audio_processors.h" | # include "juce_audio_processors/juce_audio_processors.h" | ||||
| @@ -59,161 +61,6 @@ _CarlaCachedPluginInfo::_CarlaCachedPluginInfo() noexcept | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| const char* carla_get_complete_license_text() | |||||
| { | |||||
| carla_debug("carla_get_complete_license_text()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| "<p>This current Carla build is using the following features and 3rd-party code:</p>" | |||||
| "<ul>" | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) || ! defined(VESTIGE_HEADER) | |||||
| # define LS_NOTE_NO "2" | |||||
| #else | |||||
| # define LS_NOTE_NO "1" | |||||
| #endif | |||||
| // Plugin formats | |||||
| "<li>LADSPA plugin support</li>" | |||||
| "<li>DSSI plugin support</li>" | |||||
| "<li>LV2 plugin support</li>" | |||||
| #ifdef VESTIGE_HEADER | |||||
| "<li>VST2 plugin support using VeSTige header by Javier Serrano Polo</li>" | |||||
| #else | |||||
| "<li>VST2 plugin support using official VST SDK 2.4 [1]</li>" | |||||
| #endif | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | |||||
| "<li>VST3 plugin support using official VST SDK 3.6 [1]</li>" | |||||
| #endif | |||||
| #ifdef CARLA_OS_MAC | |||||
| "<li>AU plugin support</li>" | |||||
| #endif | |||||
| // Sample kit libraries | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "<li>FluidSynth library for SF2 support</li>" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| "<li>LinuxSampler library for GIG and SFZ support [" LS_NOTE_NO "]</li>" | |||||
| #endif | |||||
| // misc libs | |||||
| "<li>base64 utilities based on code by Ren\u00E9 Nyffenegger</li>" | |||||
| #ifdef CARLA_OS_MAC | |||||
| "<li>sem_timedwait for Mac OS by Keith Shortridge</li>" | |||||
| #endif | |||||
| "<li>liblo library for OSC support</li>" | |||||
| "<li>rtmempool library by Nedko Arnaudov" | |||||
| "<li>serd, sord, sratom and lilv libraries for LV2 discovery</li>" | |||||
| #if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) | |||||
| "<li>RtAudio and RtMidi libraries for extra Audio and MIDI support</li>" | |||||
| #endif | |||||
| // Internal plugins | |||||
| #ifdef HAVE_EXPERIMENTAL_PLUGINS | |||||
| "<li>AT1, BLS1 and REV1 plugin code by Fons Adriaensen</li>" | |||||
| #endif | |||||
| "<li>MIDI Sequencer UI code by Perry Nguyen</li>" | |||||
| "<li>MVerb plugin code by Martin Eastwood</li>" | |||||
| "<li>Nekobi plugin code based on nekobee by Sean Bolton and others</li>" | |||||
| "<li>VectorJuice and WobbleJuice plugin code by Andre Sklenar</li>" | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| "<li>ZynAddSubFX plugin code by Mark McCurry and Nasca Octavian Paul</li>" | |||||
| #endif | |||||
| // end | |||||
| "</ul>" | |||||
| "<p>" | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) || ! defined(VESTIGE_HEADER) | |||||
| // Required by VST SDK | |||||
| " [1] Trademark of Steinberg Media Technologies GmbH.<br/>" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| // LinuxSampler GPL exception | |||||
| " [" LS_NOTE_NO "] Using LinuxSampler code in commercial hardware or software products is not allowed without prior written authorization by the authors." | |||||
| #endif | |||||
| "</p>" | |||||
| ; | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| const char* carla_get_juce_version() | |||||
| { | |||||
| carla_debug("carla_get_juce_version()"); | |||||
| static CarlaString retVersion; | |||||
| if (retVersion.isEmpty()) | |||||
| { | |||||
| if (const char* const version = juce::SystemStats::getJUCEVersion().toRawUTF8()) | |||||
| retVersion = version+6; | |||||
| else | |||||
| retVersion = "3.0"; | |||||
| } | |||||
| return retVersion; | |||||
| } | |||||
| const char* carla_get_supported_file_extensions() | |||||
| { | |||||
| carla_debug("carla_get_supported_file_extensions()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| // Base types | |||||
| "*.carxp;*.carxs" | |||||
| // MIDI files | |||||
| ";*.mid;*.midi" | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| // fluidsynth (sf2) | |||||
| ";*.sf2" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| // linuxsampler (gig and sfz) | |||||
| ";*.gig;*.sfz" | |||||
| #endif | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| // zynaddsubfx presets | |||||
| ";*.xmz;*.xiz" | |||||
| #endif | |||||
| ; | |||||
| // Audio files | |||||
| { | |||||
| using namespace juce; | |||||
| AudioFormatManager afm; | |||||
| afm.registerBasicFormats(); | |||||
| String juceFormats; | |||||
| for (AudioFormat **it=afm.begin(), **end=afm.end(); it != end; ++it) | |||||
| { | |||||
| const StringArray& exts((*it)->getFileExtensions()); | |||||
| for (String *eit=exts.begin(), *eend=exts.end(); eit != eend; ++eit) | |||||
| juceFormats += String(";*" + (*eit)).toRawUTF8(); | |||||
| } | |||||
| retText += juceFormats.toRawUTF8(); | |||||
| } | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| uint carla_get_cached_plugin_count(CB::PluginType ptype, const char* pluginPath) | uint carla_get_cached_plugin_count(CB::PluginType ptype, const char* pluginPath) | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(ptype == CB::PLUGIN_INTERNAL || ptype == CB::PLUGIN_LV2 || ptype == CB::PLUGIN_AU, 0); | CARLA_SAFE_ASSERT_RETURN(ptype == CB::PLUGIN_INTERNAL || ptype == CB::PLUGIN_LV2 || ptype == CB::PLUGIN_AU, 0); | ||||
| @@ -650,6 +497,161 @@ const CarlaCachedPluginInfo* carla_get_cached_plugin_info(CB::PluginType ptype, | |||||
| return &info; | return &info; | ||||
| } | } | ||||
| #ifndef CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| // ------------------------------------------------------------------------------------------------------------------- | |||||
| const char* carla_get_complete_license_text() | |||||
| { | |||||
| carla_debug("carla_get_complete_license_text()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| "<p>This current Carla build is using the following features and 3rd-party code:</p>" | |||||
| "<ul>" | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) || ! defined(VESTIGE_HEADER) | |||||
| # define LS_NOTE_NO "2" | |||||
| #else | |||||
| # define LS_NOTE_NO "1" | |||||
| #endif | |||||
| // Plugin formats | |||||
| "<li>LADSPA plugin support</li>" | |||||
| "<li>DSSI plugin support</li>" | |||||
| "<li>LV2 plugin support</li>" | |||||
| #ifdef VESTIGE_HEADER | |||||
| "<li>VST2 plugin support using VeSTige header by Javier Serrano Polo</li>" | |||||
| #else | |||||
| "<li>VST2 plugin support using official VST SDK 2.4 [1]</li>" | |||||
| #endif | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) | |||||
| "<li>VST3 plugin support using official VST SDK 3.6 [1]</li>" | |||||
| #endif | |||||
| #ifdef CARLA_OS_MAC | |||||
| "<li>AU plugin support</li>" | |||||
| #endif | |||||
| // Sample kit libraries | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| "<li>FluidSynth library for SF2 support</li>" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| "<li>LinuxSampler library for GIG and SFZ support [" LS_NOTE_NO "]</li>" | |||||
| #endif | |||||
| // misc libs | |||||
| "<li>base64 utilities based on code by Ren\u00E9 Nyffenegger</li>" | |||||
| #ifdef CARLA_OS_MAC | |||||
| "<li>sem_timedwait for Mac OS by Keith Shortridge</li>" | |||||
| #endif | |||||
| "<li>liblo library for OSC support</li>" | |||||
| "<li>rtmempool library by Nedko Arnaudov" | |||||
| "<li>serd, sord, sratom and lilv libraries for LV2 discovery</li>" | |||||
| #if ! (defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)) | |||||
| "<li>RtAudio and RtMidi libraries for extra Audio and MIDI support</li>" | |||||
| #endif | |||||
| // Internal plugins | |||||
| #ifdef HAVE_EXPERIMENTAL_PLUGINS | |||||
| "<li>AT1, BLS1 and REV1 plugin code by Fons Adriaensen</li>" | |||||
| #endif | |||||
| "<li>MIDI Sequencer UI code by Perry Nguyen</li>" | |||||
| "<li>Nekobi plugin code based on nekobee by Sean Bolton and others</li>" | |||||
| "<li>VectorJuice and WobbleJuice plugin code by Andre Sklenar</li>" | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| "<li>ZynAddSubFX plugin code by Mark McCurry and Nasca Octavian Paul</li>" | |||||
| #endif | |||||
| // end | |||||
| "</ul>" | |||||
| "<p>" | |||||
| #if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN) || ! defined(VESTIGE_HEADER) | |||||
| // Required by VST SDK | |||||
| " [1] Trademark of Steinberg Media Technologies GmbH.<br/>" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| // LinuxSampler GPL exception | |||||
| " [" LS_NOTE_NO "] Using LinuxSampler code in commercial hardware or software products is not allowed without prior written authorization by the authors." | |||||
| #endif | |||||
| "</p>" | |||||
| ; | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| const char* carla_get_juce_version() | |||||
| { | |||||
| carla_debug("carla_get_juce_version()"); | |||||
| static CarlaString retVersion; | |||||
| if (retVersion.isEmpty()) | |||||
| { | |||||
| if (const char* const version = juce::SystemStats::getJUCEVersion().toRawUTF8()) | |||||
| retVersion = version+6; | |||||
| else | |||||
| retVersion = "3.0"; | |||||
| } | |||||
| return retVersion; | |||||
| } | |||||
| const char* carla_get_supported_file_extensions() | |||||
| { | |||||
| carla_debug("carla_get_supported_file_extensions()"); | |||||
| static CarlaString retText; | |||||
| if (retText.isEmpty()) | |||||
| { | |||||
| retText = | |||||
| // Base types | |||||
| "*.carxp;*.carxs" | |||||
| // MIDI files | |||||
| ";*.mid;*.midi" | |||||
| #ifdef HAVE_FLUIDSYNTH | |||||
| // fluidsynth (sf2) | |||||
| ";*.sf2" | |||||
| #endif | |||||
| #ifdef HAVE_LINUXSAMPLER | |||||
| // linuxsampler (gig and sfz) | |||||
| ";*.gig;*.sfz" | |||||
| #endif | |||||
| #ifdef HAVE_ZYN_DEPS | |||||
| // zynaddsubfx presets | |||||
| ";*.xmz;*.xiz" | |||||
| #endif | |||||
| ; | |||||
| // Audio files | |||||
| { | |||||
| using namespace juce; | |||||
| AudioFormatManager afm; | |||||
| afm.registerBasicFormats(); | |||||
| String juceFormats; | |||||
| for (AudioFormat **it=afm.begin(), **end=afm.end(); it != end; ++it) | |||||
| { | |||||
| const StringArray& exts((*it)->getFileExtensions()); | |||||
| for (String *eit=exts.begin(), *eend=exts.end(); eit != eend; ++eit) | |||||
| juceFormats += String(";*" + (*eit)).toRawUTF8(); | |||||
| } | |||||
| retText += juceFormats.toRawUTF8(); | |||||
| } | |||||
| } | |||||
| return retText; | |||||
| } | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| void carla_set_process_name(const char* name) | void carla_set_process_name(const char* name) | ||||
| @@ -825,3 +827,4 @@ const char* carla_get_library_folder() | |||||
| #include "CarlaPipeUtils.cpp" | #include "CarlaPipeUtils.cpp" | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| #endif // CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| @@ -19,7 +19,6 @@ | |||||
| * - complete processRack(): carefully add to input, sorted events | * - complete processRack(): carefully add to input, sorted events | ||||
| * - implement processPatchbay() | * - implement processPatchbay() | ||||
| * - implement oscSend_control_switch_plugins() | * - implement oscSend_control_switch_plugins() | ||||
| * - proper find&load plugins | |||||
| * - something about the peaks? | * - something about the peaks? | ||||
| */ | */ | ||||
| @@ -37,11 +36,13 @@ | |||||
| #include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
| #include "juce_core/juce_core.h" | #include "juce_core/juce_core.h" | ||||
| using juce::Array; | |||||
| using juce::CharPointer_UTF8; | using juce::CharPointer_UTF8; | ||||
| using juce::File; | using juce::File; | ||||
| using juce::MemoryOutputStream; | using juce::MemoryOutputStream; | ||||
| using juce::ScopedPointer; | using juce::ScopedPointer; | ||||
| using juce::String; | using juce::String; | ||||
| using juce::StringArray; | |||||
| using juce::XmlDocument; | using juce::XmlDocument; | ||||
| using juce::XmlElement; | using juce::XmlElement; | ||||
| @@ -489,6 +490,8 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, | |||||
| preferBridges = true; | preferBridges = true; | ||||
| else if (uniqueId == 1397578034 && std::strstr(filename, "/Zebra2.") != nullptr) | else if (uniqueId == 1397578034 && std::strstr(filename, "/Zebra2.") != nullptr) | ||||
| preferBridges = true; | preferBridges = true; | ||||
| else if (uniqueId == 1397573722 && std::strstr(filename, "/ZebraHZ.") != nullptr) | |||||
| preferBridges = true; | |||||
| } | } | ||||
| // FIXME: linuxsampler inside carla-rack/patchbay plugin has some issues (only last kit makes noise) | // FIXME: linuxsampler inside carla-rack/patchbay plugin has some issues (only last kit makes noise) | ||||
| else if (getType() == kEngineTypePlugin && (ptype == PLUGIN_GIG || ptype == PLUGIN_SFZ)) | else if (getType() == kEngineTypePlugin && (ptype == PLUGIN_GIG || ptype == PLUGIN_SFZ)) | ||||
| @@ -1844,6 +1847,70 @@ void CarlaEngine::saveProjectInternal(juce::MemoryOutputStream& outStream) const | |||||
| outStream << "</CARLA-PROJECT>\n"; | outStream << "</CARLA-PROJECT>\n"; | ||||
| } | } | ||||
| static String findBinaryInCustomPath(const char* const searchPath, const char* const binary) | |||||
| { | |||||
| const StringArray searchPaths(StringArray::fromTokens(searchPath, CARLA_OS_SPLIT_STR, "")); | |||||
| // try direct filename first | |||||
| String jbinary(binary); | |||||
| // adjust for current platform | |||||
| #ifdef CARLA_OS_WIN | |||||
| if (jbinary[0] == '/') | |||||
| jbinary = "C:" + jbinary.replaceCharacter('/', '\\'); | |||||
| #else | |||||
| if (jbinary[1] == ':' && jbinary[2] == '\\') | |||||
| jbinary = jbinary.substring(2).replaceCharacter('\\', '/'); | |||||
| #endif | |||||
| String filename = File(jbinary).getFileName(); | |||||
| int searchFlags = File::findFiles|File::ignoreHiddenFiles; | |||||
| #ifdef CARLA_OS_MAC | |||||
| if (filename.endsWithIgnoreCase(".vst") || filename.endsWithIgnoreCase(".vst3")) | |||||
| searchFlags |= File::findDirectories; | |||||
| #endif | |||||
| Array<File> results; | |||||
| for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) | |||||
| { | |||||
| const File path(*it); | |||||
| results.clear(); | |||||
| path.findChildFiles(results, searchFlags, true, filename); | |||||
| if (results.size() > 0) | |||||
| return results.getFirst().getFullPathName(); | |||||
| } | |||||
| // try changing extension | |||||
| #if defined(CARLA_OS_MAC) | |||||
| if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".so")) | |||||
| filename = File(jbinary).getFileNameWithoutExtension() + ".dylib"; | |||||
| #elif defined(CARLA_OS_WIN) | |||||
| if (filename.endsWithIgnoreCase(".dylib") || filename.endsWithIgnoreCase(".so")) | |||||
| filename = File(jbinary).getFileNameWithoutExtension() + ".dll"; | |||||
| #else | |||||
| if (filename.endsWithIgnoreCase(".dll") || filename.endsWithIgnoreCase(".dylib")) | |||||
| filename = File(jbinary).getFileNameWithoutExtension() + ".so"; | |||||
| #endif | |||||
| else | |||||
| return String(); | |||||
| for (const String *it=searchPaths.begin(), *end=searchPaths.end(); it != end; ++it) | |||||
| { | |||||
| const File path(*it); | |||||
| results.clear(); | |||||
| path.findChildFiles(results, searchFlags, true, filename); | |||||
| if (results.size() > 0) | |||||
| return results.getFirst().getFullPathName(); | |||||
| } | |||||
| return String(); | |||||
| } | |||||
| bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | ||||
| { | { | ||||
| ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true)); | ScopedPointer<XmlElement> xmlElement(xmlDoc.getDocumentElement(true)); | ||||
| @@ -2001,23 +2068,66 @@ bool CarlaEngine::loadProjectInternal(juce::XmlDocument& xmlDoc) | |||||
| CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr); | CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr); | ||||
| const void* extraStuff = nullptr; | |||||
| // check if using GIG or SF2 16outs | |||||
| static const char kTrue[] = "true"; | |||||
| static const char kUse16OutsSuffix[] = " (16 outs)"; | |||||
| const void* extraStuff = nullptr; | |||||
| static const char kTrue[] = "true"; | |||||
| const BinaryType btype(getBinaryTypeFromFile(stateSave.binary)); | |||||
| const PluginType ptype(getPluginTypeFromString(stateSave.type)); | const PluginType ptype(getPluginTypeFromString(stateSave.type)); | ||||
| if ((ptype == PLUGIN_GIG || ptype == PLUGIN_SF2) && CarlaString(stateSave.label).endsWith(kUse16OutsSuffix)) | |||||
| switch (ptype) | |||||
| { | { | ||||
| extraStuff = kTrue; | |||||
| case PLUGIN_GIG: | |||||
| case PLUGIN_SF2: | |||||
| if (CarlaString(stateSave.label).endsWith(" (16 outs)")) | |||||
| extraStuff = kTrue; | |||||
| // nobreak | |||||
| case PLUGIN_LADSPA: | |||||
| case PLUGIN_DSSI: | |||||
| case PLUGIN_VST2: | |||||
| case PLUGIN_VST3: | |||||
| case PLUGIN_SFZ: | |||||
| if (stateSave.binary != nullptr && stateSave.binary[0] != '\0' && | |||||
| ! (File::isAbsolutePath(stateSave.binary) && File(stateSave.binary).exists())) | |||||
| { | |||||
| const char* searchPath; | |||||
| switch (ptype) | |||||
| { | |||||
| case PLUGIN_LADSPA: searchPath = pData->options.pathLADSPA; break; | |||||
| case PLUGIN_DSSI: searchPath = pData->options.pathDSSI; break; | |||||
| case PLUGIN_VST2: searchPath = pData->options.pathVST2; break; | |||||
| case PLUGIN_VST3: searchPath = pData->options.pathVST3; break; | |||||
| case PLUGIN_GIG: searchPath = pData->options.pathGIG; break; | |||||
| case PLUGIN_SF2: searchPath = pData->options.pathSF2; break; | |||||
| case PLUGIN_SFZ: searchPath = pData->options.pathSFZ; break; | |||||
| default: searchPath = nullptr; break; | |||||
| } | |||||
| if (searchPath != nullptr && searchPath[0] != '\0') | |||||
| { | |||||
| carla_stderr("Plugin binary '%s' doesn't exist on this filesystem, let's look for it...", | |||||
| stateSave.binary); | |||||
| const String result(findBinaryInCustomPath(searchPath, stateSave.binary)); | |||||
| if (result.isNotEmpty()) | |||||
| { | |||||
| delete[] stateSave.binary; | |||||
| stateSave.binary = carla_strdup(result.toRawUTF8()); | |||||
| carla_stderr("Found it! :)"); | |||||
| } | |||||
| else | |||||
| { | |||||
| carla_stderr("Damn, we failed... :("); | |||||
| } | |||||
| } | |||||
| } | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | } | ||||
| // TODO - proper find&load plugins | |||||
| if (addPlugin(btype, ptype, stateSave.binary, stateSave.name, stateSave.label, stateSave.uniqueId, extraStuff, stateSave.options)) | |||||
| if (addPlugin(getBinaryTypeFromFile(stateSave.binary), ptype, stateSave.binary, | |||||
| stateSave.name, stateSave.label, stateSave.uniqueId, extraStuff, stateSave.options)) | |||||
| { | { | ||||
| if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | if (CarlaPlugin* const plugin = getPlugin(pData->curPluginCount-1)) | ||||
| { | { | ||||
| @@ -27,6 +27,11 @@ | |||||
| #include "CarlaBridgeUtils.hpp" | #include "CarlaBridgeUtils.hpp" | ||||
| #include "CarlaMIDI.h" | #include "CarlaMIDI.h" | ||||
| #ifdef __SSE2_MATH__ | |||||
| # include <xmmintrin.h> | |||||
| #endif | |||||
| // must be last | |||||
| #include "jackbridge/JackBridge.hpp" | #include "jackbridge/JackBridge.hpp" | ||||
| using juce::File; | using juce::File; | ||||
| @@ -561,6 +566,7 @@ public: | |||||
| char bufStr[STR_MAX+1]; | char bufStr[STR_MAX+1]; | ||||
| uint32_t bufStrSize; | uint32_t bufStrSize; | ||||
| const CarlaEngineClient* const client(plugin->getEngineClient()); | |||||
| const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); | ||||
| // kPluginBridgeNonRtServerPluginInfo1 | // kPluginBridgeNonRtServerPluginInfo1 | ||||
| @@ -609,13 +615,50 @@ public: | |||||
| // kPluginBridgeNonRtServerAudioCount | // kPluginBridgeNonRtServerAudioCount | ||||
| { | { | ||||
| const uint32_t aIns = plugin->getAudioInCount(); | |||||
| const uint32_t aOuts = plugin->getAudioOutCount(); | |||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); | fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); | ||||
| fShmNonRtServerControl.writeUInt(plugin->getAudioInCount()); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getAudioOutCount()); | |||||
| fShmNonRtServerControl.writeUInt(aIns); | |||||
| fShmNonRtServerControl.writeUInt(aOuts); | |||||
| fShmNonRtServerControl.commitWrite(); | fShmNonRtServerControl.commitWrite(); | ||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aIns; ++i) | |||||
| { | |||||
| const char* const portName(client->getAudioPortName(true, i)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioInput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = std::strlen(portName); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(portName, bufStrSize); | |||||
| } | |||||
| // kPluginBridgeNonRtServerPortName | |||||
| for (uint32_t i=0; i<aOuts; ++i) | |||||
| { | |||||
| const char* const portName(client->getAudioPortName(false, i)); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(portName != nullptr && portName[0] != '\0'); | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPortName); | |||||
| fShmNonRtServerControl.writeByte(kPluginBridgePortAudioOutput); | |||||
| fShmNonRtServerControl.writeUInt(i); | |||||
| bufStrSize = std::strlen(portName); | |||||
| fShmNonRtServerControl.writeUInt(bufStrSize); | |||||
| fShmNonRtServerControl.writeCustomData(portName, bufStrSize); | |||||
| } | |||||
| } | } | ||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // kPluginBridgeNonRtServerMidiCount | // kPluginBridgeNonRtServerMidiCount | ||||
| { | { | ||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| @@ -627,6 +670,17 @@ public: | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | fShmNonRtServerControl.waitIfDataIsReachingLimit(); | ||||
| // kPluginBridgeNonRtServerCvCount | |||||
| { | |||||
| // uint/ins, uint/outs | |||||
| fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerCvCount); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getCVInCount()); | |||||
| fShmNonRtServerControl.writeUInt(plugin->getCVOutCount()); | |||||
| fShmNonRtServerControl.commitWrite(); | |||||
| } | |||||
| fShmNonRtServerControl.waitIfDataIsReachingLimit(); | |||||
| // kPluginBridgeNonRtServerParameter* | // kPluginBridgeNonRtServerParameter* | ||||
| if (const uint32_t count = plugin->getParameterCount()) | if (const uint32_t count = plugin->getParameterCount()) | ||||
| { | { | ||||
| @@ -1205,6 +1259,11 @@ public: | |||||
| protected: | protected: | ||||
| void run() override | void run() override | ||||
| { | { | ||||
| #ifdef __SSE2_MATH__ | |||||
| // Set FTZ and DAZ flags | |||||
| _mm_setcsr(_mm_getcsr() | 0x8040); | |||||
| #endif | |||||
| bool quitReceived = false; | bool quitReceived = false; | ||||
| for (; ! threadShouldExit();) | for (; ! threadShouldExit();) | ||||
| @@ -38,6 +38,7 @@ using juce::FloatVectorOperations; | |||||
| using juce::MemoryBlock; | using juce::MemoryBlock; | ||||
| using juce::PluginDescription; | using juce::PluginDescription; | ||||
| using juce::String; | using juce::String; | ||||
| using juce::StringArray; | |||||
| using juce::jmin; | using juce::jmin; | ||||
| using juce::jmax; | using juce::jmax; | ||||
| @@ -343,9 +344,9 @@ void ExternalGraph::refresh(const char* const deviceName) | |||||
| char strBuf[STR_MAX+1]; | char strBuf[STR_MAX+1]; | ||||
| strBuf[STR_MAX] = '\0'; | strBuf[STR_MAX] = '\0'; | ||||
| // Audio In | |||||
| if (isRack) | if (isRack) | ||||
| { | { | ||||
| // Audio In | |||||
| if (deviceName[0] != '\0') | if (deviceName[0] != '\0') | ||||
| std::snprintf(strBuf, STR_MAX, "Capture (%s)", deviceName); | std::snprintf(strBuf, STR_MAX, "Capture (%s)", deviceName); | ||||
| else | else | ||||
| @@ -353,22 +354,19 @@ void ExternalGraph::refresh(const char* const deviceName) | |||||
| kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioIn, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioIn, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | ||||
| const CarlaString groupName(strBuf); | |||||
| const CarlaString groupNameIn(strBuf); | |||||
| int h = 0; | int h = 0; | ||||
| for (LinkedList<PortNameToId>::Itenerator it = audioPorts.ins.begin2(); it.valid(); it.next()) | for (LinkedList<PortNameToId>::Itenerator it = audioPorts.ins.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| PortNameToId& portNameToId(it.getValue()); | PortNameToId& portNameToId(it.getValue()); | ||||
| portNameToId.setFullName(groupName + portNameToId.name); | |||||
| portNameToId.setFullName(groupNameIn + portNameToId.name); | |||||
| kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioIn, ++h, | kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioIn, ++h, | ||||
| PATCHBAY_PORT_TYPE_AUDIO, 0.0f, portNameToId.name); | PATCHBAY_PORT_TYPE_AUDIO, 0.0f, portNameToId.name); | ||||
| } | } | ||||
| } | |||||
| // Audio Out | |||||
| if (isRack) | |||||
| { | |||||
| // Audio Out | |||||
| if (deviceName[0] != '\0') | if (deviceName[0] != '\0') | ||||
| std::snprintf(strBuf, STR_MAX, "Playback (%s)", deviceName); | std::snprintf(strBuf, STR_MAX, "Playback (%s)", deviceName); | ||||
| else | else | ||||
| @@ -376,13 +374,13 @@ void ExternalGraph::refresh(const char* const deviceName) | |||||
| kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioOut, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | kEngine->callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, kExternalGraphGroupAudioOut, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | ||||
| const CarlaString groupName(strBuf); | |||||
| const CarlaString groupNameOut(strBuf); | |||||
| int h = 0; | |||||
| h = 0; | |||||
| for (LinkedList<PortNameToId>::Itenerator it = audioPorts.outs.begin2(); it.valid(); it.next()) | for (LinkedList<PortNameToId>::Itenerator it = audioPorts.outs.begin2(); it.valid(); it.next()) | ||||
| { | { | ||||
| PortNameToId& portNameToId(it.getValue()); | PortNameToId& portNameToId(it.getValue()); | ||||
| portNameToId.setFullName(groupName + portNameToId.name); | |||||
| portNameToId.setFullName(groupNameOut + portNameToId.name); | |||||
| kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioOut, ++h, | kEngine->callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, kExternalGraphGroupAudioOut, ++h, | ||||
| PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | ||||
| @@ -1343,13 +1341,46 @@ private: | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Patchbay Graph | // Patchbay Graph | ||||
| class NamedAudioGraphIOProcessor : public AudioProcessorGraph::AudioGraphIOProcessor | |||||
| { | |||||
| public: | |||||
| NamedAudioGraphIOProcessor(const IODeviceType type) | |||||
| : AudioProcessorGraph::AudioGraphIOProcessor(type) {} | |||||
| const String getInputChannelName (int index) const override | |||||
| { | |||||
| if (index < inputNames.size()) | |||||
| return inputNames[index]; | |||||
| return String("Playback ") + String(index+1); | |||||
| } | |||||
| const String getOutputChannelName (int index) const override | |||||
| { | |||||
| if (index < outputNames.size()) | |||||
| return outputNames[index]; | |||||
| return String("Capture ") + String(index+1); | |||||
| } | |||||
| void setNames(const bool isInput, const StringArray& names) | |||||
| { | |||||
| if (isInput) | |||||
| inputNames = names; | |||||
| else | |||||
| outputNames = names; | |||||
| } | |||||
| private: | |||||
| StringArray inputNames; | |||||
| StringArray outputNames; | |||||
| }; | |||||
| PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, const uint32_t outs) | PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, const uint32_t outs) | ||||
| : connections(), | : connections(), | ||||
| graph(), | graph(), | ||||
| audioBuffer(), | audioBuffer(), | ||||
| midiBuffer(), | midiBuffer(), | ||||
| inputs(carla_fixedValue(0U, MAX_PATCHBAY_PLUGINS-2, ins)), | |||||
| outputs(carla_fixedValue(0U, MAX_PATCHBAY_PLUGINS-2, outs)), | |||||
| inputs(carla_fixedValue(0U, 32U, ins)), | |||||
| outputs(carla_fixedValue(0U, 32U, outs)), | |||||
| retCon(), | retCon(), | ||||
| usingExternal(false), | usingExternal(false), | ||||
| extGraph(engine), | extGraph(engine), | ||||
| @@ -1366,8 +1397,30 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
| midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); | midiBuffer.ensureSize(kMaxEngineEventInternalCount*2); | ||||
| midiBuffer.clear(); | midiBuffer.clear(); | ||||
| StringArray channelNames; | |||||
| switch (inputs) | |||||
| { | { | ||||
| AudioProcessorGraph::AudioGraphIOProcessor* const proc(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioInputNode)); | |||||
| case 2: | |||||
| channelNames = { | |||||
| "Left", | |||||
| "Right", | |||||
| }; | |||||
| break; | |||||
| case 3: | |||||
| channelNames = { | |||||
| "Left", | |||||
| "Right", | |||||
| "Sidechain", | |||||
| }; | |||||
| break; | |||||
| } | |||||
| { | |||||
| NamedAudioGraphIOProcessor* const proc( | |||||
| new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioInputNode)); | |||||
| proc->setNames(false, channelNames); | |||||
| AudioProcessorGraph::Node* const node(graph.addNode(proc)); | AudioProcessorGraph::Node* const node(graph.addNode(proc)); | ||||
| node->properties.set("isPlugin", false); | node->properties.set("isPlugin", false); | ||||
| node->properties.set("isOutput", false); | node->properties.set("isOutput", false); | ||||
| @@ -1378,7 +1431,10 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
| } | } | ||||
| { | { | ||||
| AudioProcessorGraph::AudioGraphIOProcessor* const proc(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::audioOutputNode)); | |||||
| NamedAudioGraphIOProcessor* const proc( | |||||
| new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::audioOutputNode)); | |||||
| proc->setNames(true, channelNames); | |||||
| AudioProcessorGraph::Node* const node(graph.addNode(proc)); | AudioProcessorGraph::Node* const node(graph.addNode(proc)); | ||||
| node->properties.set("isPlugin", false); | node->properties.set("isPlugin", false); | ||||
| node->properties.set("isOutput", false); | node->properties.set("isOutput", false); | ||||
| @@ -1389,7 +1445,8 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
| } | } | ||||
| { | { | ||||
| AudioProcessorGraph::AudioGraphIOProcessor* const proc(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::midiInputNode)); | |||||
| NamedAudioGraphIOProcessor* const proc( | |||||
| new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::midiInputNode)); | |||||
| AudioProcessorGraph::Node* const node(graph.addNode(proc)); | AudioProcessorGraph::Node* const node(graph.addNode(proc)); | ||||
| node->properties.set("isPlugin", false); | node->properties.set("isPlugin", false); | ||||
| node->properties.set("isOutput", false); | node->properties.set("isOutput", false); | ||||
| @@ -1400,7 +1457,8 @@ PatchbayGraph::PatchbayGraph(CarlaEngine* const engine, const uint32_t ins, cons | |||||
| } | } | ||||
| { | { | ||||
| AudioProcessorGraph::AudioGraphIOProcessor* const proc(new AudioProcessorGraph::AudioGraphIOProcessor(AudioProcessorGraph::AudioGraphIOProcessor::midiOutputNode)); | |||||
| NamedAudioGraphIOProcessor* const proc( | |||||
| new NamedAudioGraphIOProcessor(NamedAudioGraphIOProcessor::midiOutputNode)); | |||||
| AudioProcessorGraph::Node* const node(graph.addNode(proc)); | AudioProcessorGraph::Node* const node(graph.addNode(proc)); | ||||
| node->properties.set("isPlugin", false); | node->properties.set("isPlugin", false); | ||||
| node->properties.set("isOutput", true); | node->properties.set("isOutput", true); | ||||
| @@ -1226,11 +1226,14 @@ public: | |||||
| plugin->setEnabled(false); | plugin->setEnabled(false); | ||||
| // set new client data | // set new client data | ||||
| jackbridge_set_thread_init_callback(jackClient, carla_jack_thread_init_callback, nullptr); | |||||
| jackbridge_set_latency_callback(jackClient, carla_jack_latency_callback_plugin, plugin); | jackbridge_set_latency_callback(jackClient, carla_jack_latency_callback_plugin, plugin); | ||||
| jackbridge_set_process_callback(jackClient, carla_jack_process_callback_plugin, plugin); | jackbridge_set_process_callback(jackClient, carla_jack_process_callback_plugin, plugin); | ||||
| jackbridge_on_shutdown(jackClient, carla_jack_shutdown_callback_plugin, plugin); | jackbridge_on_shutdown(jackClient, carla_jack_shutdown_callback_plugin, plugin); | ||||
| // NOTE: jack1 locks up here | |||||
| if (jackbridge_get_version_string() != nullptr) | |||||
| jackbridge_set_thread_init_callback(jackClient, carla_jack_thread_init_callback, nullptr); | |||||
| /* The following code is because of a tricky situation. | /* The following code is because of a tricky situation. | ||||
| We cannot lock or do jack operations during jack callbacks on jack1. jack2 events are asynchronous. | We cannot lock or do jack operations during jack callbacks on jack1. jack2 events are asynchronous. | ||||
| When we close the client jack will trigger unregister-port callbacks, which we handle on a separate thread ASAP. | When we close the client jack will trigger unregister-port callbacks, which we handle on a separate thread ASAP. | ||||
| @@ -1256,7 +1256,11 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aIns > 1) | |||||
| if (fInfo.aInNames != nullptr && fInfo.aInNames[j] != nullptr) | |||||
| { | |||||
| portName += fInfo.aInNames[j]; | |||||
| } | |||||
| else if (fInfo.aIns > 1) | |||||
| { | { | ||||
| portName += "input_"; | portName += "input_"; | ||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| @@ -1281,7 +1285,11 @@ public: | |||||
| portName += ":"; | portName += ":"; | ||||
| } | } | ||||
| if (fInfo.aOuts > 1) | |||||
| if (fInfo.aOutNames != nullptr && fInfo.aOutNames[j] != nullptr) | |||||
| { | |||||
| portName += fInfo.aOutNames[j]; | |||||
| } | |||||
| else if (fInfo.aOuts > 1) | |||||
| { | { | ||||
| portName += "output_"; | portName += "output_"; | ||||
| portName += CarlaString(j+1); | portName += CarlaString(j+1); | ||||
| @@ -1295,6 +1303,8 @@ public: | |||||
| pData->audioOut.ports[j].rindex = j; | pData->audioOut.ports[j].rindex = j; | ||||
| } | } | ||||
| // TODO - MIDI | |||||
| // TODO - CV | // TODO - CV | ||||
| if (needsCtrlIn) | if (needsCtrlIn) | ||||
| @@ -2049,6 +2059,22 @@ public: | |||||
| // uint/ins, uint/outs | // uint/ins, uint/outs | ||||
| fInfo.aIns = fShmNonRtServerControl.readUInt(); | fInfo.aIns = fShmNonRtServerControl.readUInt(); | ||||
| fInfo.aOuts = fShmNonRtServerControl.readUInt(); | fInfo.aOuts = fShmNonRtServerControl.readUInt(); | ||||
| CARLA_SAFE_ASSERT(fInfo.aInNames == nullptr); | |||||
| CARLA_SAFE_ASSERT(fInfo.aOutNames == nullptr); | |||||
| if (fInfo.aIns > 0) | |||||
| { | |||||
| fInfo.aInNames = new const char*[fInfo.aIns]; | |||||
| carla_zeroPointers(fInfo.aInNames, fInfo.aIns); | |||||
| } | |||||
| if (fInfo.aOuts > 0) | |||||
| { | |||||
| fInfo.aOutNames = new const char*[fInfo.aOuts]; | |||||
| carla_zeroPointers(fInfo.aOutNames, fInfo.aOuts); | |||||
| } | |||||
| } break; | } break; | ||||
| case kPluginBridgeNonRtServerMidiCount: { | case kPluginBridgeNonRtServerMidiCount: { | ||||
| @@ -2057,6 +2083,12 @@ public: | |||||
| fInfo.mOuts = fShmNonRtServerControl.readUInt(); | fInfo.mOuts = fShmNonRtServerControl.readUInt(); | ||||
| } break; | } break; | ||||
| case kPluginBridgeNonRtServerCvCount: { | |||||
| // uint/ins, uint/outs | |||||
| fInfo.cvIns = fShmNonRtServerControl.readUInt(); | |||||
| fInfo.cvOuts = fShmNonRtServerControl.readUInt(); | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerParameterCount: { | case kPluginBridgeNonRtServerParameterCount: { | ||||
| // uint/count | // uint/count | ||||
| const uint32_t count = fShmNonRtServerControl.readUInt(); | const uint32_t count = fShmNonRtServerControl.readUInt(); | ||||
| @@ -2106,6 +2138,33 @@ public: | |||||
| } break; | } break; | ||||
| case kPluginBridgeNonRtServerPortName: { | |||||
| // byte/type, uint/index, uint/size, str[] (name) | |||||
| const uint8_t portType = fShmNonRtServerControl.readByte(); | |||||
| const uint32_t index = fShmNonRtServerControl.readUInt(); | |||||
| // name | |||||
| const uint32_t nameSize(fShmNonRtServerControl.readUInt()); | |||||
| char* const name = new char[nameSize+1]; | |||||
| carla_zeroChars(name, nameSize+1); | |||||
| fShmNonRtServerControl.readCustomData(name, nameSize); | |||||
| CARLA_SAFE_ASSERT_BREAK(portType > kPluginBridgePortNull && portType < kPluginBridgePortTypeCount); | |||||
| switch (portType) | |||||
| { | |||||
| case kPluginBridgePortAudioInput: | |||||
| CARLA_SAFE_ASSERT_BREAK(index < fInfo.aIns); | |||||
| fInfo.aInNames[index] = name; | |||||
| break; | |||||
| case kPluginBridgePortAudioOutput: | |||||
| CARLA_SAFE_ASSERT_BREAK(index < fInfo.aOuts); | |||||
| fInfo.aOutNames[index] = name; | |||||
| break; | |||||
| } | |||||
| } break; | |||||
| case kPluginBridgeNonRtServerParameterData1: { | case kPluginBridgeNonRtServerParameterData1: { | ||||
| // uint/index, int/rindex, uint/type, uint/hints, int/cc | // uint/index, int/rindex, uint/type, uint/hints, int/cc | ||||
| const uint32_t index = fShmNonRtServerControl.readUInt(); | const uint32_t index = fShmNonRtServerControl.readUInt(); | ||||
| @@ -2619,6 +2678,8 @@ private: | |||||
| CarlaString label; | CarlaString label; | ||||
| CarlaString maker; | CarlaString maker; | ||||
| CarlaString copyright; | CarlaString copyright; | ||||
| const char** aInNames; | |||||
| const char** aOutNames; | |||||
| std::vector<uint8_t> chunk; | std::vector<uint8_t> chunk; | ||||
| Info() | Info() | ||||
| @@ -2634,6 +2695,8 @@ private: | |||||
| label(), | label(), | ||||
| maker(), | maker(), | ||||
| copyright(), | copyright(), | ||||
| aInNames(nullptr), | |||||
| aOutNames(nullptr), | |||||
| chunk() {} | chunk() {} | ||||
| } fInfo; | } fInfo; | ||||
| @@ -757,13 +757,6 @@ public: | |||||
| return CarlaPlugin::getCategory(); | return CarlaPlugin::getCategory(); | ||||
| } | } | ||||
| int64_t getUniqueId() const noexcept override | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(fRdfDescriptor != nullptr, 0); | |||||
| return static_cast<int64_t>(fRdfDescriptor->UniqueID); | |||||
| } | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Information (count) | // Information (count) | ||||
| @@ -37,6 +37,7 @@ | |||||
| #include "CarlaVstUtils.hpp" | #include "CarlaVstUtils.hpp" | ||||
| // need to include this before linuxsampler | // need to include this before linuxsampler | ||||
| #define CARLA_UTILS_CACHED_PLUGINS_ONLY | |||||
| #include "CarlaUtils.cpp" | #include "CarlaUtils.cpp" | ||||
| #ifdef HAVE_FLUIDSYNTH | #ifdef HAVE_FLUIDSYNTH | ||||
| @@ -255,11 +255,15 @@ private: \ | |||||
| /* Define CARLA_OS_SEP */ | /* Define CARLA_OS_SEP */ | ||||
| #ifdef CARLA_OS_WIN | #ifdef CARLA_OS_WIN | ||||
| # define CARLA_OS_SEP '\\' | |||||
| # define CARLA_OS_SEP_STR "\\" | |||||
| # define CARLA_OS_SEP '\\' | |||||
| # define CARLA_OS_SEP_STR "\\" | |||||
| # define CARLA_OS_SPLIT ';' | |||||
| # define CARLA_OS_SPLIT_STR ";" | |||||
| #else | #else | ||||
| # define CARLA_OS_SEP '/' | |||||
| # define CARLA_OS_SEP_STR "/" | |||||
| # define CARLA_OS_SEP '/' | |||||
| # define CARLA_OS_SEP_STR "/" | |||||
| # define CARLA_OS_SPLIT ':' | |||||
| # define CARLA_OS_SPLIT_STR ":" | |||||
| #endif | #endif | ||||
| /* Useful typedefs */ | /* Useful typedefs */ | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_IMAGE_ABOUT_WINDOW_HPP_INCLUDED | |||||
| #define DGL_IMAGE_ABOUT_WINDOW_HPP_INCLUDED | |||||
| #warning This is a deprecated file, please include ImageWidgets.hpp instead. | |||||
| #include "ImageWidgets.hpp" | |||||
| #endif // DGL_IMAGE_ABOUT_WINDOW_HPP_INCLUDED | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_IMAGE_BUTTON_HPP_INCLUDED | |||||
| #define DGL_IMAGE_BUTTON_HPP_INCLUDED | |||||
| #warning This is a deprecated file, please include ImageWidgets.hpp instead. | |||||
| #include "ImageWidgets.hpp" | |||||
| #endif // DGL_IMAGE_BUTTON_HPP_INCLUDED | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_IMAGE_KNOB_HPP_INCLUDED | |||||
| #define DGL_IMAGE_KNOB_HPP_INCLUDED | |||||
| #warning This is a deprecated file, please include ImageWidgets.hpp instead. | |||||
| #include "ImageWidgets.hpp" | |||||
| #endif // DGL_IMAGE_KNOB_HPP_INCLUDED | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_IMAGE_SLIDER_HPP_INCLUDED | |||||
| #define DGL_IMAGE_SLIDER_HPP_INCLUDED | |||||
| #warning This is a deprecated file, please include ImageWidgets.hpp instead. | |||||
| #include "ImageWidgets.hpp" | |||||
| #endif // DGL_IMAGE_SLIDER_HPP_INCLUDED | |||||
| @@ -1,23 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_IMAGE_SWITCH_HPP_INCLUDED | |||||
| #define DGL_IMAGE_SWITCH_HPP_INCLUDED | |||||
| #warning This is a deprecated file, please include ImageWidgets.hpp instead. | |||||
| #include "ImageWidgets.hpp" | |||||
| #endif // DGL_IMAGE_SWITCH_HPP_INCLUDED | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -15,9 +15,6 @@ BUILD_CXX_FLAGS += $(DGL_FLAGS) -Isrc | |||||
| # needed by sofd right now, fix later | # needed by sofd right now, fix later | ||||
| BUILD_CXX_FLAGS += -Wno-type-limits -fpermissive | BUILD_CXX_FLAGS += -Wno-type-limits -fpermissive | ||||
| # needed by oui-blendish | |||||
| BUILD_CXX_FLAGS += -Wno-unused-parameter | |||||
| # ---------------------------------------------------------------------------------------------------------------------------- | # ---------------------------------------------------------------------------------------------------------------------------- | ||||
| OBJS = \ | OBJS = \ | ||||
| @@ -27,7 +24,6 @@ OBJS = \ | |||||
| $(OBJDIR)/Image.cpp.o \ | $(OBJDIR)/Image.cpp.o \ | ||||
| $(OBJDIR)/ImageWidgets.cpp.o \ | $(OBJDIR)/ImageWidgets.cpp.o \ | ||||
| $(OBJDIR)/NanoVG.cpp.o \ | $(OBJDIR)/NanoVG.cpp.o \ | ||||
| $(OBJDIR)/NanoWidgets.cpp.o \ | |||||
| $(OBJDIR)/Resources.cpp.o \ | $(OBJDIR)/Resources.cpp.o \ | ||||
| $(OBJDIR)/Widget.cpp.o | $(OBJDIR)/Widget.cpp.o | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,77 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DGL_NANO_WIDGETS_HPP_INCLUDED | |||||
| #define DGL_NANO_WIDGETS_HPP_INCLUDED | |||||
| #include "NanoVG.hpp" | |||||
| START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | |||||
| class BlendishWidget : public NanoWidget | |||||
| { | |||||
| public: | |||||
| explicit BlendishWidget(Window& parent); | |||||
| explicit BlendishWidget(NanoWidget* widget); | |||||
| void loadSharedResources() override; | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| class BlendishButton : public BlendishWidget | |||||
| { | |||||
| public: | |||||
| class Callback | |||||
| { | |||||
| public: | |||||
| virtual ~Callback() {} | |||||
| virtual void blendishButtonClicked(BlendishButton* blendishButton, int button) = 0; | |||||
| }; | |||||
| explicit BlendishButton(Window& parent, const char* text = "", int iconId = -1); | |||||
| explicit BlendishButton(NanoWidget* widget, const char* text = "", int iconId = -1); | |||||
| ~BlendishButton() override; | |||||
| int getIconId() const noexcept; | |||||
| void setIconId(int iconId) noexcept; | |||||
| const char* getText() const noexcept; | |||||
| void setText(const char* text) noexcept; | |||||
| void setCallback(Callback* callback) noexcept; | |||||
| protected: | |||||
| void onNanoDisplay() override; | |||||
| bool onMouse(const MouseEvent&) override; | |||||
| bool onMotion(const MotionEvent&) override; | |||||
| private: | |||||
| struct PrivateData; | |||||
| PrivateData* const pData; | |||||
| void _updateBounds(); | |||||
| DISTRHO_LEAK_DETECTOR(BlendishButton) | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||
| #endif // DGL_NANO_WIDGETS_HPP_INCLUDED | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -18,7 +18,6 @@ | |||||
| #define DGL_COMMON_HPP_INCLUDED | #define DGL_COMMON_HPP_INCLUDED | ||||
| #include "../ImageWidgets.hpp" | #include "../ImageWidgets.hpp" | ||||
| #include "../NanoWidgets.hpp" | |||||
| START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
| @@ -35,15 +34,13 @@ struct ButtonImpl { | |||||
| int state; | int state; | ||||
| Widget* self; | Widget* self; | ||||
| BlendishButton::Callback* callback_b; | |||||
| ImageButton::Callback* callback_i; | |||||
| ImageButton::Callback* callback_img; | |||||
| ButtonImpl(Widget* const s) noexcept | ButtonImpl(Widget* const s) noexcept | ||||
| : button(-1), | : button(-1), | ||||
| state(kStateNormal), | state(kStateNormal), | ||||
| self(s), | self(s), | ||||
| callback_b(nullptr), | |||||
| callback_i(nullptr) {} | |||||
| callback_img(nullptr) {} | |||||
| bool onMouse(const Widget::MouseEvent& ev) | bool onMouse(const Widget::MouseEvent& ev) | ||||
| { | { | ||||
| @@ -68,10 +65,8 @@ struct ButtonImpl { | |||||
| state = kStateHover; | state = kStateHover; | ||||
| self->repaint(); | self->repaint(); | ||||
| if (callback_b != nullptr) | |||||
| callback_b->blendishButtonClicked((BlendishButton*)self, button2); | |||||
| if (callback_i != nullptr) | |||||
| callback_i->imageButtonClicked((ImageButton*)self, button2); | |||||
| if (callback_img != nullptr) | |||||
| callback_img->imageButtonClicked((ImageButton*)self, button2); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -159,7 +159,7 @@ ImageButton::~ImageButton() | |||||
| void ImageButton::setCallback(Callback* callback) noexcept | void ImageButton::setCallback(Callback* callback) noexcept | ||||
| { | { | ||||
| pData->impl.callback_i = callback; | |||||
| pData->impl.callback_img = callback; | |||||
| } | } | ||||
| void ImageButton::onDisplay() | void ImageButton::onDisplay() | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,152 +0,0 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #include "Common.hpp" | |||||
| #include "Resources.hpp" | |||||
| #define BLENDISH_IMPLEMENTATION | |||||
| #include "nanovg/nanovg.h" | |||||
| #include "oui-blendish/blendish.h" | |||||
| #include "../distrho/extra/String.hpp" | |||||
| START_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | |||||
| BlendishWidget::BlendishWidget(Window& parent) | |||||
| : NanoWidget(parent) | |||||
| { | |||||
| loadSharedResources(); | |||||
| } | |||||
| BlendishWidget::BlendishWidget(NanoWidget* widget) | |||||
| : NanoWidget(widget) | |||||
| { | |||||
| loadSharedResources(); | |||||
| } | |||||
| void BlendishWidget::loadSharedResources() | |||||
| { | |||||
| if (nvgFindFont(fContext, NANOVG_DEJAVU_SANS_TTF) >= 0) | |||||
| return; | |||||
| using namespace dpf_resources; | |||||
| bndSetFont(nvgCreateFontMem(fContext, NANOVG_DEJAVU_SANS_TTF, (const uchar*)dejavusans_ttf, dejavusans_ttf_size, 0)); | |||||
| bndSetIconImage(nvgCreateImageMem(fContext, 0, (const uchar*)blender_icons16_png, blender_icons16_png_size)); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| struct BlendishButton::PrivateData { | |||||
| ButtonImpl impl; | |||||
| int iconId; | |||||
| DISTRHO_NAMESPACE::String text; | |||||
| PrivateData(Widget* const s, const char* const t, const int i) noexcept | |||||
| : impl(s), | |||||
| iconId(i), | |||||
| text(t) {} | |||||
| DISTRHO_DECLARE_NON_COPY_STRUCT(PrivateData) | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| BlendishButton::BlendishButton(Window& parent, const char* text, int iconId) | |||||
| : BlendishWidget(parent), | |||||
| pData(new PrivateData(this, text, iconId)) | |||||
| { | |||||
| _updateBounds(); | |||||
| } | |||||
| BlendishButton::BlendishButton(NanoWidget* widget, const char* text, int iconId) | |||||
| : BlendishWidget(widget), | |||||
| pData(new PrivateData(this, text, iconId)) | |||||
| { | |||||
| _updateBounds(); | |||||
| } | |||||
| BlendishButton::~BlendishButton() | |||||
| { | |||||
| delete pData; | |||||
| } | |||||
| int BlendishButton::getIconId() const noexcept | |||||
| { | |||||
| return pData->iconId; | |||||
| } | |||||
| void BlendishButton::setIconId(int iconId) noexcept | |||||
| { | |||||
| if (pData->iconId == iconId) | |||||
| return; | |||||
| pData->iconId = iconId; | |||||
| _updateBounds(); | |||||
| repaint(); | |||||
| } | |||||
| const char* BlendishButton::getText() const noexcept | |||||
| { | |||||
| return pData->text; | |||||
| } | |||||
| void BlendishButton::setText(const char* text) noexcept | |||||
| { | |||||
| if (pData->text == text) | |||||
| return; | |||||
| pData->text = text; | |||||
| _updateBounds(); | |||||
| repaint(); | |||||
| } | |||||
| void BlendishButton::setCallback(Callback* callback) noexcept | |||||
| { | |||||
| pData->impl.callback_b = callback; | |||||
| } | |||||
| void BlendishButton::onNanoDisplay() | |||||
| { | |||||
| bndToolButton(getContext(), | |||||
| getAbsoluteX(), getAbsoluteY(), getWidth(), getHeight(), | |||||
| 0, static_cast<BNDwidgetState>(pData->impl.state), pData->iconId, pData->text); | |||||
| } | |||||
| bool BlendishButton::onMouse(const MouseEvent& ev) | |||||
| { | |||||
| return pData->impl.onMouse(ev); | |||||
| } | |||||
| bool BlendishButton::onMotion(const MotionEvent& ev) | |||||
| { | |||||
| return pData->impl.onMotion(ev); | |||||
| } | |||||
| void BlendishButton::_updateBounds() | |||||
| { | |||||
| const float width = bndLabelWidth (getContext(), pData->iconId, pData->text); | |||||
| const float height = bndLabelHeight(getContext(), pData->iconId, pData->text, width); | |||||
| setSize(width, height); | |||||
| } | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DGL | |||||
| // ----------------------------------------------------------------------- | |||||
| @@ -5,11 +5,8 @@ | |||||
| namespace dpf_resources | namespace dpf_resources | ||||
| { | { | ||||
| extern const char* blender_icons16_png; | |||||
| const unsigned int blender_icons16_png_size = 250706; | |||||
| extern const char* dejavusans_ttf; | |||||
| const unsigned int dejavusans_ttf_size = 741536; | |||||
| extern const char* dejavusans_ttf; | |||||
| const unsigned int dejavusans_ttf_size = 741536; | |||||
| }; | }; | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,21 +0,0 @@ | |||||
| Blendish - Blender 2.5 UI based theming functions for NanoVG | |||||
| Copyright (c) 2014 Leonard Ritter <leonard.ritter@duangle.com> | |||||
| 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. | |||||
| 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. | |||||
| @@ -1,280 +0,0 @@ | |||||
| GNU GENERAL PUBLIC LICENSE | |||||
| Version 2, June 1991 | |||||
| Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |||||
| 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||||
| Everyone is permitted to copy and distribute verbatim copies | |||||
| of this license document, but changing it is not allowed. | |||||
| Preamble | |||||
| The licenses for most software are designed to take away your | |||||
| freedom to share and change it. By contrast, the GNU General Public | |||||
| License is intended to guarantee your freedom to share and change free | |||||
| software--to make sure the software is free for all its users. This | |||||
| General Public License applies to most of the Free Software | |||||
| Foundation's software and to any other program whose authors commit to | |||||
| using it. (Some other Free Software Foundation software is covered by | |||||
| the GNU Library General Public License instead.) You can apply it to | |||||
| your programs, too. | |||||
| When we speak of free software, we are referring to freedom, not | |||||
| price. Our General Public Licenses are designed to make sure that you | |||||
| have the freedom to distribute copies of free software (and charge for | |||||
| this service if you wish), that you receive source code or can get it | |||||
| if you want it, that you can change the software or use pieces of it | |||||
| in new free programs; and that you know you can do these things. | |||||
| To protect your rights, we need to make restrictions that forbid | |||||
| anyone to deny you these rights or to ask you to surrender the rights. | |||||
| These restrictions translate to certain responsibilities for you if you | |||||
| distribute copies of the software, or if you modify it. | |||||
| For example, if you distribute copies of such a program, whether | |||||
| gratis or for a fee, you must give the recipients all the rights that | |||||
| you have. You must make sure that they, too, receive or can get the | |||||
| source code. And you must show them these terms so they know their | |||||
| rights. | |||||
| We protect your rights with two steps: (1) copyright the software, and | |||||
| (2) offer you this license which gives you legal permission to copy, | |||||
| distribute and/or modify the software. | |||||
| Also, for each author's protection and ours, we want to make certain | |||||
| that everyone understands that there is no warranty for this free | |||||
| software. If the software is modified by someone else and passed on, we | |||||
| want its recipients to know that what they have is not the original, so | |||||
| that any problems introduced by others will not reflect on the original | |||||
| authors' reputations. | |||||
| Finally, any free program is threatened constantly by software | |||||
| patents. We wish to avoid the danger that redistributors of a free | |||||
| program will individually obtain patent licenses, in effect making the | |||||
| program proprietary. To prevent this, we have made it clear that any | |||||
| patent must be licensed for everyone's free use or not licensed at all. | |||||
| The precise terms and conditions for copying, distribution and | |||||
| modification follow. | |||||
| GNU GENERAL PUBLIC LICENSE | |||||
| TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||||
| 0. This License applies to any program or other work which contains | |||||
| a notice placed by the copyright holder saying it may be distributed | |||||
| under the terms of this General Public License. The "Program", below, | |||||
| refers to any such program or work, and a "work based on the Program" | |||||
| means either the Program or any derivative work under copyright law: | |||||
| that is to say, a work containing the Program or a portion of it, | |||||
| either verbatim or with modifications and/or translated into another | |||||
| language. (Hereinafter, translation is included without limitation in | |||||
| the term "modification".) Each licensee is addressed as "you". | |||||
| Activities other than copying, distribution and modification are not | |||||
| covered by this License; they are outside its scope. The act of | |||||
| running the Program is not restricted, and the output from the Program | |||||
| is covered only if its contents constitute a work based on the | |||||
| Program (independent of having been made by running the Program). | |||||
| Whether that is true depends on what the Program does. | |||||
| 1. You may copy and distribute verbatim copies of the Program's | |||||
| source code as you receive it, in any medium, provided that you | |||||
| conspicuously and appropriately publish on each copy an appropriate | |||||
| copyright notice and disclaimer of warranty; keep intact all the | |||||
| notices that refer to this License and to the absence of any warranty; | |||||
| and give any other recipients of the Program a copy of this License | |||||
| along with the Program. | |||||
| You may charge a fee for the physical act of transferring a copy, and | |||||
| you may at your option offer warranty protection in exchange for a fee. | |||||
| 2. You may modify your copy or copies of the Program or any portion | |||||
| of it, thus forming a work based on the Program, and copy and | |||||
| distribute such modifications or work under the terms of Section 1 | |||||
| above, provided that you also meet all of these conditions: | |||||
| a) You must cause the modified files to carry prominent notices | |||||
| stating that you changed the files and the date of any change. | |||||
| b) You must cause any work that you distribute or publish, that in | |||||
| whole or in part contains or is derived from the Program or any | |||||
| part thereof, to be licensed as a whole at no charge to all third | |||||
| parties under the terms of this License. | |||||
| c) If the modified program normally reads commands interactively | |||||
| when run, you must cause it, when started running for such | |||||
| interactive use in the most ordinary way, to print or display an | |||||
| announcement including an appropriate copyright notice and a | |||||
| notice that there is no warranty (or else, saying that you provide | |||||
| a warranty) and that users may redistribute the program under | |||||
| these conditions, and telling the user how to view a copy of this | |||||
| License. (Exception: if the Program itself is interactive but | |||||
| does not normally print such an announcement, your work based on | |||||
| the Program is not required to print an announcement.) | |||||
| These requirements apply to the modified work as a whole. If | |||||
| identifiable sections of that work are not derived from the Program, | |||||
| and can be reasonably considered independent and separate works in | |||||
| themselves, then this License, and its terms, do not apply to those | |||||
| sections when you distribute them as separate works. But when you | |||||
| distribute the same sections as part of a whole which is a work based | |||||
| on the Program, the distribution of the whole must be on the terms of | |||||
| this License, whose permissions for other licensees extend to the | |||||
| entire whole, and thus to each and every part regardless of who wrote it. | |||||
| Thus, it is not the intent of this section to claim rights or contest | |||||
| your rights to work written entirely by you; rather, the intent is to | |||||
| exercise the right to control the distribution of derivative or | |||||
| collective works based on the Program. | |||||
| In addition, mere aggregation of another work not based on the Program | |||||
| with the Program (or with a work based on the Program) on a volume of | |||||
| a storage or distribution medium does not bring the other work under | |||||
| the scope of this License. | |||||
| 3. You may copy and distribute the Program (or a work based on it, | |||||
| under Section 2) in object code or executable form under the terms of | |||||
| Sections 1 and 2 above provided that you also do one of the following: | |||||
| a) Accompany it with the complete corresponding machine-readable | |||||
| source code, which must be distributed under the terms of Sections | |||||
| 1 and 2 above on a medium customarily used for software interchange; or, | |||||
| b) Accompany it with a written offer, valid for at least three | |||||
| years, to give any third party, for a charge no more than your | |||||
| cost of physically performing source distribution, a complete | |||||
| machine-readable copy of the corresponding source code, to be | |||||
| distributed under the terms of Sections 1 and 2 above on a medium | |||||
| customarily used for software interchange; or, | |||||
| c) Accompany it with the information you received as to the offer | |||||
| to distribute corresponding source code. (This alternative is | |||||
| allowed only for noncommercial distribution and only if you | |||||
| received the program in object code or executable form with such | |||||
| an offer, in accord with Subsection b above.) | |||||
| The source code for a work means the preferred form of the work for | |||||
| making modifications to it. For an executable work, complete source | |||||
| code means all the source code for all modules it contains, plus any | |||||
| associated interface definition files, plus the scripts used to | |||||
| control compilation and installation of the executable. However, as a | |||||
| special exception, the source code distributed need not include | |||||
| anything that is normally distributed (in either source or binary | |||||
| form) with the major components (compiler, kernel, and so on) of the | |||||
| operating system on which the executable runs, unless that component | |||||
| itself accompanies the executable. | |||||
| If distribution of executable or object code is made by offering | |||||
| access to copy from a designated place, then offering equivalent | |||||
| access to copy the source code from the same place counts as | |||||
| distribution of the source code, even though third parties are not | |||||
| compelled to copy the source along with the object code. | |||||
| 4. You may not copy, modify, sublicense, or distribute the Program | |||||
| except as expressly provided under this License. Any attempt | |||||
| otherwise to copy, modify, sublicense or distribute the Program is | |||||
| void, and will automatically terminate your rights under this License. | |||||
| However, parties who have received copies, or rights, from you under | |||||
| this License will not have their licenses terminated so long as such | |||||
| parties remain in full compliance. | |||||
| 5. You are not required to accept this License, since you have not | |||||
| signed it. However, nothing else grants you permission to modify or | |||||
| distribute the Program or its derivative works. These actions are | |||||
| prohibited by law if you do not accept this License. Therefore, by | |||||
| modifying or distributing the Program (or any work based on the | |||||
| Program), you indicate your acceptance of this License to do so, and | |||||
| all its terms and conditions for copying, distributing or modifying | |||||
| the Program or works based on it. | |||||
| 6. Each time you redistribute the Program (or any work based on the | |||||
| Program), the recipient automatically receives a license from the | |||||
| original licensor to copy, distribute or modify the Program subject to | |||||
| these terms and conditions. You may not impose any further | |||||
| restrictions on the recipients' exercise of the rights granted herein. | |||||
| You are not responsible for enforcing compliance by third parties to | |||||
| this License. | |||||
| 7. If, as a consequence of a court judgment or allegation of patent | |||||
| infringement or for any other reason (not limited to patent issues), | |||||
| conditions are imposed on you (whether by court order, agreement or | |||||
| otherwise) that contradict the conditions of this License, they do not | |||||
| excuse you from the conditions of this License. If you cannot | |||||
| distribute so as to satisfy simultaneously your obligations under this | |||||
| License and any other pertinent obligations, then as a consequence you | |||||
| may not distribute the Program at all. For example, if a patent | |||||
| license would not permit royalty-free redistribution of the Program by | |||||
| all those who receive copies directly or indirectly through you, then | |||||
| the only way you could satisfy both it and this License would be to | |||||
| refrain entirely from distribution of the Program. | |||||
| If any portion of this section is held invalid or unenforceable under | |||||
| any particular circumstance, the balance of the section is intended to | |||||
| apply and the section as a whole is intended to apply in other | |||||
| circumstances. | |||||
| It is not the purpose of this section to induce you to infringe any | |||||
| patents or other property right claims or to contest validity of any | |||||
| such claims; this section has the sole purpose of protecting the | |||||
| integrity of the free software distribution system, which is | |||||
| implemented by public license practices. Many people have made | |||||
| generous contributions to the wide range of software distributed | |||||
| through that system in reliance on consistent application of that | |||||
| system; it is up to the author/donor to decide if he or she is willing | |||||
| to distribute software through any other system and a licensee cannot | |||||
| impose that choice. | |||||
| This section is intended to make thoroughly clear what is believed to | |||||
| be a consequence of the rest of this License. | |||||
| 8. If the distribution and/or use of the Program is restricted in | |||||
| certain countries either by patents or by copyrighted interfaces, the | |||||
| original copyright holder who places the Program under this License | |||||
| may add an explicit geographical distribution limitation excluding | |||||
| those countries, so that distribution is permitted only in or among | |||||
| countries not thus excluded. In such case, this License incorporates | |||||
| the limitation as if written in the body of this License. | |||||
| 9. The Free Software Foundation may publish revised and/or new versions | |||||
| of the General Public License from time to time. Such new versions will | |||||
| be similar in spirit to the present version, but may differ in detail to | |||||
| address new problems or concerns. | |||||
| Each version is given a distinguishing version number. If the Program | |||||
| specifies a version number of this License which applies to it and "any | |||||
| later version", you have the option of following the terms and conditions | |||||
| either of that version or of any later version published by the Free | |||||
| Software Foundation. If the Program does not specify a version number of | |||||
| this License, you may choose any version ever published by the Free Software | |||||
| Foundation. | |||||
| 10. If you wish to incorporate parts of the Program into other free | |||||
| programs whose distribution conditions are different, write to the author | |||||
| to ask for permission. For software which is copyrighted by the Free | |||||
| Software Foundation, write to the Free Software Foundation; we sometimes | |||||
| make exceptions for this. Our decision will be guided by the two goals | |||||
| of preserving the free status of all derivatives of our free software and | |||||
| of promoting the sharing and reuse of software generally. | |||||
| NO WARRANTY | |||||
| 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |||||
| FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |||||
| OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |||||
| PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |||||
| OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||||
| MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |||||
| TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |||||
| PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |||||
| REPAIR OR CORRECTION. | |||||
| 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |||||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |||||
| REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |||||
| INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |||||
| OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |||||
| TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |||||
| YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |||||
| PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |||||
| POSSIBILITY OF SUCH DAMAGES. | |||||
| END OF TERMS AND CONDITIONS | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -20,7 +20,10 @@ | |||||
| #include "extra/LeakDetector.hpp" | #include "extra/LeakDetector.hpp" | ||||
| #include "src/DistrhoPluginChecks.h" | #include "src/DistrhoPluginChecks.h" | ||||
| #if DISTRHO_UI_USE_NANOVG | |||||
| #ifndef HAVE_DGL | |||||
| # include "extra/ExternalWindow.hpp" | |||||
| typedef DISTRHO_NAMESPACE::ExternalWindow UIWidget; | |||||
| #elif DISTRHO_UI_USE_NANOVG | |||||
| # include "../dgl/NanoVG.hpp" | # include "../dgl/NanoVG.hpp" | ||||
| typedef DGL::NanoWidget UIWidget; | typedef DGL::NanoWidget UIWidget; | ||||
| #else | #else | ||||
| @@ -41,9 +44,8 @@ START_NAMESPACE_DISTRHO | |||||
| /** | /** | ||||
| DPF UI class from where UI instances are created. | DPF UI class from where UI instances are created. | ||||
| TODO. | |||||
| must call setSize during construction, | |||||
| @note You must call setSize during construction, | |||||
| @TODO Detailed information about this class. | |||||
| */ | */ | ||||
| class UI : public UIWidget | class UI : public UIWidget | ||||
| { | { | ||||
| @@ -69,25 +71,29 @@ public: | |||||
| double getSampleRate() const noexcept; | double getSampleRate() const noexcept; | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| editParameter. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| void editParameter(uint32_t index, bool started); | void editParameter(uint32_t index, bool started); | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| setParameterValue. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| void setParameterValue(uint32_t index, float value); | void setParameterValue(uint32_t index, float value); | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| setState. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| void setState(const char* key, const char* value); | void setState(const char* key, const char* value); | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_IS_SYNTH | #if DISTRHO_PLUGIN_IS_SYNTH | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| sendNote. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| void sendNote(uint8_t channel, uint8_t note, uint8_t velocity); | void sendNote(uint8_t channel, uint8_t note, uint8_t velocity); | ||||
| #endif | #endif | ||||
| @@ -97,11 +103,24 @@ public: | |||||
| * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */ | * Direct DSP access - DO NOT USE THIS UNLESS STRICTLY NECESSARY!! */ | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| getPluginInstancePointer. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| void* getPluginInstancePointer() const noexcept; | void* getPluginInstancePointer() const noexcept; | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_HAS_EMBED_UI && DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| /* -------------------------------------------------------------------------------------------------------- | |||||
| * External embeddable UI helpers */ | |||||
| /** | |||||
| Get the Window Id that will be used for the next created window. | |||||
| @note: This function is only valid during createUI(), | |||||
| it will return 0 when called from anywhere else. | |||||
| */ | |||||
| static uintptr_t getNextWindowId() noexcept; | |||||
| #endif | |||||
| protected: | protected: | ||||
| /* -------------------------------------------------------------------------------------------------------- | /* -------------------------------------------------------------------------------------------------------- | ||||
| * DSP/Plugin Callbacks */ | * DSP/Plugin Callbacks */ | ||||
| @@ -137,11 +156,13 @@ protected: | |||||
| */ | */ | ||||
| virtual void sampleRateChanged(double newSampleRate); | virtual void sampleRateChanged(double newSampleRate); | ||||
| #ifdef HAVE_DGL | |||||
| /* -------------------------------------------------------------------------------------------------------- | /* -------------------------------------------------------------------------------------------------------- | ||||
| * UI Callbacks (optional) */ | * UI Callbacks (optional) */ | ||||
| /** | /** | ||||
| TODO: Document this. | |||||
| uiIdle. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| virtual void uiIdle() {} | virtual void uiIdle() {} | ||||
| @@ -167,6 +188,7 @@ protected: | |||||
| @see Widget::onResize(const ResizeEvent&) | @see Widget::onResize(const ResizeEvent&) | ||||
| */ | */ | ||||
| void onResize(const ResizeEvent& ev) override; | void onResize(const ResizeEvent& ev) override; | ||||
| #endif | |||||
| // ------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------- | ||||
| @@ -176,11 +198,13 @@ private: | |||||
| friend class UIExporter; | friend class UIExporter; | ||||
| friend class UIExporterWindow; | friend class UIExporterWindow; | ||||
| #ifdef HAVE_DGL | |||||
| // these should not be used | // these should not be used | ||||
| void setAbsoluteX(int) const noexcept {} | void setAbsoluteX(int) const noexcept {} | ||||
| void setAbsoluteY(int) const noexcept {} | void setAbsoluteY(int) const noexcept {} | ||||
| void setAbsolutePos(int, int) const noexcept {} | void setAbsolutePos(int, int) const noexcept {} | ||||
| void setAbsolutePos(const DGL::Point<int>&) const noexcept {} | void setAbsolutePos(const DGL::Point<int>&) const noexcept {} | ||||
| #endif | |||||
| DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(UI) | ||||
| }; | }; | ||||
| @@ -196,7 +220,8 @@ private: | |||||
| */ | */ | ||||
| /** | /** | ||||
| TODO. | |||||
| createUI. | |||||
| @TODO Document this. | |||||
| */ | */ | ||||
| extern UI* createUI(); | extern UI* createUI(); | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -24,7 +24,30 @@ | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // base64 stuff, based on http://www.adp-gmbh.ch/cpp/common/base64.html | // base64 stuff, based on http://www.adp-gmbh.ch/cpp/common/base64.html | ||||
| // Copyright (C) 2004-2008 René Nyffenegger | |||||
| /* | |||||
| Copyright (C) 2004-2008 René Nyffenegger | |||||
| This source code is provided 'as-is', without any express or implied | |||||
| warranty. In no event will the author be held liable for any damages | |||||
| arising from the use of this software. | |||||
| Permission is granted to anyone to use this software for any purpose, | |||||
| including commercial applications, and to alter it and redistribute it | |||||
| freely, subject to the following restrictions: | |||||
| 1. The origin of this source code must not be misrepresented; you must not | |||||
| claim that you wrote the original source code. If you use this source code | |||||
| in a product, an acknowledgment in the product documentation would be | |||||
| appreciated but is not required. | |||||
| 2. Altered source versions must be plainly marked as such, and must not be | |||||
| misrepresented as being the original source code. | |||||
| 3. This notice may not be removed or altered from any source distribution. | |||||
| René Nyffenegger rene.nyffenegger@adp-gmbh.ch | |||||
| */ | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Helpers | // Helpers | ||||
| @@ -0,0 +1,171 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Framework (DPF) | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | |||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | |||||
| * or without fee is hereby granted, provided that the above copyright notice and this | |||||
| * permission notice appear in all copies. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||||
| * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||||
| * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||||
| * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||||
| * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| */ | |||||
| #ifndef DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED | |||||
| #define DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED | |||||
| #include "String.hpp" | |||||
| #ifdef DISTRHO_OS_UNIX | |||||
| # include <cerrno> | |||||
| # include <sys/wait.h> | |||||
| # include <unistd.h> | |||||
| #else | |||||
| # error Unsupported platform! | |||||
| #endif | |||||
| START_NAMESPACE_DISTRHO | |||||
| // ----------------------------------------------------------------------- | |||||
| // ExternalWindow class | |||||
| class ExternalWindow | |||||
| { | |||||
| public: | |||||
| ExternalWindow(const uint w = 1, const uint h = 1, const char* const t = "") | |||||
| : width(w), | |||||
| height(h), | |||||
| title(t), | |||||
| pid(0) {} | |||||
| virtual ~ExternalWindow() | |||||
| { | |||||
| terminateAndWaitForProcess(); | |||||
| } | |||||
| uint getWidth() const noexcept | |||||
| { | |||||
| return width; | |||||
| } | |||||
| uint getHeight() const noexcept | |||||
| { | |||||
| return height; | |||||
| } | |||||
| const char* getTitle() const noexcept | |||||
| { | |||||
| return title; | |||||
| } | |||||
| void setTitle(const char* const t) noexcept | |||||
| { | |||||
| title = t; | |||||
| } | |||||
| bool isRunning() noexcept | |||||
| { | |||||
| if (pid <= 0) | |||||
| return false; | |||||
| const pid_t p = ::waitpid(pid, nullptr, WNOHANG); | |||||
| if (p == pid || (p == -1 && errno == ECHILD)) | |||||
| { | |||||
| printf("NOTICE: Child process exited while idle\n"); | |||||
| pid = 0; | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| protected: | |||||
| bool startExternalProcess(const char* args[]) | |||||
| { | |||||
| terminateAndWaitForProcess(); | |||||
| pid = vfork(); | |||||
| switch (pid) | |||||
| { | |||||
| case 0: | |||||
| execvp(args[0], (char**)args); | |||||
| _exit(1); | |||||
| return false; | |||||
| case -1: | |||||
| printf("Could not start external ui\n"); | |||||
| return false; | |||||
| default: | |||||
| return true; | |||||
| } | |||||
| } | |||||
| private: | |||||
| uint width; | |||||
| uint height; | |||||
| String title; | |||||
| pid_t pid; | |||||
| friend class UIExporter; | |||||
| void terminateAndWaitForProcess() | |||||
| { | |||||
| if (pid <= 0) | |||||
| return; | |||||
| printf("Waiting for previous process to stop,,,\n"); | |||||
| bool sendTerm = true; | |||||
| for (pid_t p;;) | |||||
| { | |||||
| p = ::waitpid(pid, nullptr, WNOHANG); | |||||
| switch (p) | |||||
| { | |||||
| case 0: | |||||
| if (sendTerm) | |||||
| { | |||||
| sendTerm = false; | |||||
| ::kill(pid, SIGTERM); | |||||
| } | |||||
| break; | |||||
| case -1: | |||||
| if (errno == ECHILD) | |||||
| { | |||||
| printf("Done! (no such process)\n"); | |||||
| pid = 0; | |||||
| return; | |||||
| } | |||||
| break; | |||||
| default: | |||||
| if (p == pid) | |||||
| { | |||||
| printf("Done! (clean wait)\n"); | |||||
| pid = 0; | |||||
| return; | |||||
| } | |||||
| break; | |||||
| } | |||||
| // 5 msec | |||||
| usleep(5*1000); | |||||
| } | |||||
| } | |||||
| DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow) | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| END_NAMESPACE_DISTRHO | |||||
| #endif // DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED | |||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -54,11 +54,20 @@ public: | |||||
| /* | /* | ||||
| * Simple char string. | * Simple char string. | ||||
| */ | */ | ||||
| explicit String(char* const strBuf) noexcept | |||||
| explicit String(char* const strBuf, const bool copyData = true) noexcept | |||||
| : fBuffer(_null()), | : fBuffer(_null()), | ||||
| fBufferLen(0) | fBufferLen(0) | ||||
| { | { | ||||
| _dup(strBuf); | |||||
| if (copyData || strBuf == nullptr) | |||||
| { | |||||
| _dup(strBuf); | |||||
| } | |||||
| else | |||||
| { | |||||
| fBuffer = strBuf; | |||||
| fBufferLen = std::strlen(strBuf); | |||||
| } | |||||
| } | } | ||||
| /* | /* | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -42,6 +42,10 @@ | |||||
| # endif | # endif | ||||
| #endif | #endif | ||||
| #if defined(DISTRHO_OS_LINUX) || defined(DISTRHO_OS_MAC) | |||||
| # define DISTRHO_OS_UNIX | |||||
| #endif | |||||
| #ifndef DISTRHO_DLL_EXTENSION | #ifndef DISTRHO_DLL_EXTENSION | ||||
| # define DISTRHO_DLL_EXTENSION "so" | # define DISTRHO_DLL_EXTENSION "so" | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU Lesser General Public | * modify it under the terms of the GNU Lesser General Public | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -45,6 +45,10 @@ | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| #ifndef DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| # define DISTRHO_PLUGIN_HAS_EXTERNAL_UI 0 | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_IS_RT_SAFE | #ifndef DISTRHO_PLUGIN_IS_RT_SAFE | ||||
| # define DISTRHO_PLUGIN_IS_RT_SAFE 0 | # define DISTRHO_PLUGIN_IS_RT_SAFE 0 | ||||
| #endif | #endif | ||||
| @@ -85,6 +89,17 @@ | |||||
| # define DISTRHO_UI_USE_NANOVG 0 | # define DISTRHO_UI_USE_NANOVG 0 | ||||
| #endif | #endif | ||||
| // ----------------------------------------------------------------------- | |||||
| // Define DISTRHO_PLUGIN_HAS_EMBED_UI if needed | |||||
| #ifndef DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| # ifdef HAVE_DGL | |||||
| # define DISTRHO_PLUGIN_HAS_EMBED_UI 1 | |||||
| # else | |||||
| # define DISTRHO_PLUGIN_HAS_EMBED_UI 0 | |||||
| # endif | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Define DISTRHO_UI_URI if needed | // Define DISTRHO_UI_URI if needed | ||||
| @@ -117,9 +132,9 @@ | |||||
| #endif | #endif | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Disable UI if DGL is not available | |||||
| // Disable UI if DGL or External UI is not available | |||||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||||
| #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI && ! defined(HAVE_DGL) | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | # undef DISTRHO_PLUGIN_HAS_UI | ||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
| * modify it under the terms of the GNU Lesser General Public | * modify it under the terms of the GNU Lesser General Public | ||||
| @@ -16,7 +16,7 @@ | |||||
| #include "DistrhoPluginInternal.hpp" | #include "DistrhoPluginInternal.hpp" | ||||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||||
| #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | # undef DISTRHO_PLUGIN_HAS_UI | ||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -49,12 +49,7 @@ | |||||
| # define DISTRHO_PLUGIN_USES_MODGUI 0 | # define DISTRHO_PLUGIN_USES_MODGUI 0 | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | |||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | |||||
| #endif | |||||
| #if DISTRHO_PLUGIN_HAS_UI | |||||
| #if DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| # if DISTRHO_OS_HAIKU | # if DISTRHO_OS_HAIKU | ||||
| # define DISTRHO_LV2_UI_TYPE "BeUI" | # define DISTRHO_LV2_UI_TYPE "BeUI" | ||||
| # elif DISTRHO_OS_MAC | # elif DISTRHO_OS_MAC | ||||
| @@ -64,6 +59,8 @@ | |||||
| # else | # else | ||||
| # define DISTRHO_LV2_UI_TYPE "X11UI" | # define DISTRHO_LV2_UI_TYPE "X11UI" | ||||
| # endif | # endif | ||||
| #else | |||||
| # define DISTRHO_LV2_UI_TYPE "UI" | |||||
| #endif | #endif | ||||
| #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | #define DISTRHO_LV2_USE_EVENTS_IN (DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || (DISTRHO_PLUGIN_WANT_STATE && DISTRHO_PLUGIN_HAS_UI)) | ||||
| @@ -137,10 +134,12 @@ void lv2_generate_ttl(const char* const basename) | |||||
| manifestString += " ui:showInterface ;\n"; | manifestString += " ui:showInterface ;\n"; | ||||
| # endif | # endif | ||||
| manifestString += "\n"; | manifestString += "\n"; | ||||
| # if DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; | manifestString += " lv2:optionalFeature ui:noUserResize ,\n"; | ||||
| manifestString += " ui:resize ,\n"; | manifestString += " ui:resize ,\n"; | ||||
| manifestString += " ui:touch ;\n"; | manifestString += " ui:touch ;\n"; | ||||
| manifestString += "\n"; | manifestString += "\n"; | ||||
| # endif | |||||
| manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n"; | manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n"; | ||||
| manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; | manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n"; | ||||
| manifestString += " <" LV2_OPTIONS__options "> ,\n"; | manifestString += " <" LV2_OPTIONS__options "> ,\n"; | ||||
| @@ -558,10 +557,12 @@ void lv2_generate_ttl(const char* const basename) | |||||
| uiString += " ui:showInterface ;\n"; | uiString += " ui:showInterface ;\n"; | ||||
| # endif | # endif | ||||
| uiString += "\n"; | uiString += "\n"; | ||||
| # if DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| uiString += " lv2:optionalFeature ui:noUserResize ,\n"; | uiString += " lv2:optionalFeature ui:noUserResize ,\n"; | ||||
| uiString += " ui:resize ,\n"; | uiString += " ui:resize ,\n"; | ||||
| uiString += " ui:touch ;\n"; | uiString += " ui:touch ;\n"; | ||||
| uiString += "\n"; | uiString += "\n"; | ||||
| # endif | |||||
| uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | uiString += " lv2:requiredFeature <" LV2_OPTIONS__options "> ,\n"; | ||||
| uiString += " <" LV2_URID__map "> .\n"; | uiString += " <" LV2_URID__map "> .\n"; | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -16,7 +16,7 @@ | |||||
| #include "DistrhoPluginInternal.hpp" | #include "DistrhoPluginInternal.hpp" | ||||
| #if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||||
| #if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EMBED_UI | |||||
| # undef DISTRHO_PLUGIN_HAS_UI | # undef DISTRHO_PLUGIN_HAS_UI | ||||
| # define DISTRHO_PLUGIN_HAS_UI 0 | # define DISTRHO_PLUGIN_HAS_UI 0 | ||||
| #endif | #endif | ||||
| @@ -340,6 +340,10 @@ public: | |||||
| intptr_t vst_dispatcher(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) | intptr_t vst_dispatcher(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) | ||||
| { | { | ||||
| #if DISTRHO_PLUGIN_WANT_STATE | |||||
| intptr_t ret = 0; | |||||
| #endif | |||||
| switch (opcode) | switch (opcode) | ||||
| { | { | ||||
| case effGetProgram: | case effGetProgram: | ||||
| @@ -512,7 +516,7 @@ public: | |||||
| { | { | ||||
| fStateChunk = new char[1]; | fStateChunk = new char[1]; | ||||
| fStateChunk[0] = '\0'; | fStateChunk[0] = '\0'; | ||||
| return 1; | |||||
| ret = 1; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -546,7 +550,7 @@ public: | |||||
| fStateChunk = new char[chunkSize]; | fStateChunk = new char[chunkSize]; | ||||
| std::memcpy(fStateChunk, chunkStr.buffer(), chunkStr.length()); | std::memcpy(fStateChunk, chunkStr.buffer(), chunkStr.length()); | ||||
| fStateChunk[chunkSize] = '\0'; | |||||
| fStateChunk[chunkSize-1] = '\0'; | |||||
| for (std::size_t i=0; i<chunkSize; ++i) | for (std::size_t i=0; i<chunkSize; ++i) | ||||
| { | { | ||||
| @@ -554,11 +558,11 @@ public: | |||||
| fStateChunk[i] = '\0'; | fStateChunk[i] = '\0'; | ||||
| } | } | ||||
| return chunkSize; | |||||
| ret = chunkSize; | |||||
| } | } | ||||
| *(void**)ptr = fStateChunk; | *(void**)ptr = fStateChunk; | ||||
| break; | |||||
| return ret; | |||||
| case effSetChunk: | case effSetChunk: | ||||
| { | { | ||||
| @@ -634,36 +638,38 @@ public: | |||||
| } | } | ||||
| break; | break; | ||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT || DISTRHO_PLUGIN_WANT_MIDI_OUTPUT || DISTRHO_PLUGIN_WANT_TIMEPOS || DISTRHO_OS_MAC | |||||
| case effCanDo: | case effCanDo: | ||||
| if (const char* const canDo = (const char*)ptr) | if (const char* const canDo = (const char*)ptr) | ||||
| { | { | ||||
| # if DISTRHO_OS_MAC && DISTRHO_PLUGIN_HAS_UI | |||||
| #if DISTRHO_OS_MAC && DISTRHO_PLUGIN_HAS_UI | |||||
| if (std::strcmp(canDo, "hasCockosViewAsConfig") == 0) | if (std::strcmp(canDo, "hasCockosViewAsConfig") == 0) | ||||
| { | { | ||||
| fUsingNsView = true; | fUsingNsView = true; | ||||
| return 0xbeef0000; | return 0xbeef0000; | ||||
| } | } | ||||
| # endif | |||||
| # if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| if (std::strcmp(canDo, "receiveVstEvents") == 0) | |||||
| return 1; | |||||
| if (std::strcmp(canDo, "receiveVstMidiEvent") == 0) | |||||
| return 1; | |||||
| # endif | |||||
| # if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |||||
| if (std::strcmp(canDo, "sendVstEvents") == 0) | |||||
| #endif | |||||
| if (std::strcmp(canDo, "receiveVstEvents") == 0 || | |||||
| std::strcmp(canDo, "receiveVstMidiEvent") == 0) | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_INPUT | |||||
| return 1; | return 1; | ||||
| if (std::strcmp(canDo, "sendVstMidiEvent") == 0) | |||||
| #else | |||||
| return -1; | |||||
| #endif | |||||
| if (std::strcmp(canDo, "sendVstEvents") == 0 || | |||||
| std::strcmp(canDo, "sendVstMidiEvent") == 0) | |||||
| #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT | |||||
| return 1; | return 1; | ||||
| # endif | |||||
| # if DISTRHO_PLUGIN_WANT_TIMEPOS | |||||
| #else | |||||
| return -1; | |||||
| #endif | |||||
| if (std::strcmp(canDo, "receiveVstTimeInfo") == 0) | if (std::strcmp(canDo, "receiveVstTimeInfo") == 0) | ||||
| #if DISTRHO_PLUGIN_WANT_TIMEPOS | |||||
| return 1; | return 1; | ||||
| # endif | |||||
| #else | |||||
| return -1; | |||||
| #endif | |||||
| } | } | ||||
| break; | break; | ||||
| #endif | |||||
| //case effStartProcess: | //case effStartProcess: | ||||
| //case effStopProcess: | //case effStopProcess: | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -15,20 +15,27 @@ | |||||
| */ | */ | ||||
| #include "DistrhoUIInternal.hpp" | #include "DistrhoUIInternal.hpp" | ||||
| #include "src/WidgetPrivateData.hpp" | |||||
| #ifdef HAVE_DGL | |||||
| # include "src/WidgetPrivateData.hpp" | |||||
| #endif | |||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * Static data, see DistrhoUIInternal.hpp */ | * Static data, see DistrhoUIInternal.hpp */ | ||||
| double d_lastUiSampleRate = 0.0; | |||||
| void* d_lastUiDspPtr = nullptr; | |||||
| Window* d_lastUiWindow = nullptr; | |||||
| double d_lastUiSampleRate = 0.0; | |||||
| void* d_lastUiDspPtr = nullptr; | |||||
| #ifdef HAVE_DGL | |||||
| Window* d_lastUiWindow = nullptr; | |||||
| #endif | |||||
| uintptr_t g_nextWindowId = 0; | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI */ | * UI */ | ||||
| #ifdef HAVE_DGL | |||||
| UI::UI(uint width, uint height) | UI::UI(uint width, uint height) | ||||
| : UIWidget(*d_lastUiWindow), | : UIWidget(*d_lastUiWindow), | ||||
| pData(new PrivateData()) | pData(new PrivateData()) | ||||
| @@ -38,6 +45,11 @@ UI::UI(uint width, uint height) | |||||
| if (width > 0 && height > 0) | if (width > 0 && height > 0) | ||||
| setSize(width, height); | setSize(width, height); | ||||
| } | } | ||||
| #else | |||||
| UI::UI(uint width, uint height) | |||||
| : UIWidget(width, height), | |||||
| pData(new PrivateData()) {} | |||||
| #endif | |||||
| UI::~UI() | UI::~UI() | ||||
| { | { | ||||
| @@ -86,11 +98,22 @@ void* UI::getPluginInstancePointer() const noexcept | |||||
| } | } | ||||
| #endif | #endif | ||||
| #if DISTRHO_PLUGIN_HAS_EMBED_UI && DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||||
| /* ------------------------------------------------------------------------------------------------------------ | |||||
| * External embeddable UI helpers */ | |||||
| uintptr_t UI::getNextWindowId() noexcept | |||||
| { | |||||
| return g_nextWindowId; | |||||
| } | |||||
| #endif | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * DSP/Plugin Callbacks (optional) */ | * DSP/Plugin Callbacks (optional) */ | ||||
| void UI::sampleRateChanged(double) {} | void UI::sampleRateChanged(double) {} | ||||
| #ifdef HAVE_DGL | |||||
| /* ------------------------------------------------------------------------------------------------------------ | /* ------------------------------------------------------------------------------------------------------------ | ||||
| * UI Callbacks (optional) */ | * UI Callbacks (optional) */ | ||||
| @@ -117,6 +140,7 @@ void UI::onResize(const ResizeEvent& ev) | |||||
| { | { | ||||
| pData->setSizeCallback(ev.size.getWidth(), ev.size.getHeight()); | pData->setSizeCallback(ev.size.getWidth(), ev.size.getHeight()); | ||||
| } | } | ||||
| #endif | |||||
| // ----------------------------------------------------------------------------------------------------------- | // ----------------------------------------------------------------------------------------------------------- | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -18,21 +18,26 @@ | |||||
| #define DISTRHO_UI_INTERNAL_HPP_INCLUDED | #define DISTRHO_UI_INTERNAL_HPP_INCLUDED | ||||
| #include "../DistrhoUI.hpp" | #include "../DistrhoUI.hpp" | ||||
| #include "../../dgl/Application.hpp" | |||||
| #include "../../dgl/Window.hpp" | |||||
| #ifdef HAVE_DGL | |||||
| # include "../../dgl/Application.hpp" | |||||
| # include "../../dgl/Window.hpp" | |||||
| using DGL::Application; | using DGL::Application; | ||||
| using DGL::IdleCallback; | using DGL::IdleCallback; | ||||
| using DGL::Window; | using DGL::Window; | ||||
| #endif | |||||
| START_NAMESPACE_DISTRHO | START_NAMESPACE_DISTRHO | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Static data, see DistrhoUI.cpp | // Static data, see DistrhoUI.cpp | ||||
| extern double d_lastUiSampleRate; | |||||
| extern void* d_lastUiDspPtr; | |||||
| extern Window* d_lastUiWindow; | |||||
| extern double d_lastUiSampleRate; | |||||
| extern void* d_lastUiDspPtr; | |||||
| #ifdef HAVE_DGL | |||||
| extern Window* d_lastUiWindow; | |||||
| #endif | |||||
| extern uintptr_t g_nextWindowId; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // UI callbacks | // UI callbacks | ||||
| @@ -128,6 +133,7 @@ struct UI::PrivateData { | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // Plugin Window, needed to take care of resize properly | // Plugin Window, needed to take care of resize properly | ||||
| #ifdef HAVE_DGL | |||||
| static inline | static inline | ||||
| UI* createUiWrapper(void* const dspPtr, Window* const window) | UI* createUiWrapper(void* const dspPtr, Window* const window) | ||||
| { | { | ||||
| @@ -191,6 +197,18 @@ private: | |||||
| UI* const fUI; | UI* const fUI; | ||||
| bool fIsReady; | bool fIsReady; | ||||
| }; | }; | ||||
| #else | |||||
| static inline | |||||
| UI* createUiWrapper(void* const dspPtr, const uintptr_t winId) | |||||
| { | |||||
| d_lastUiDspPtr = dspPtr; | |||||
| g_nextWindowId = winId; | |||||
| UI* const ret = createUI(); | |||||
| d_lastUiDspPtr = nullptr; | |||||
| g_nextWindowId = 0; | |||||
| return ret; | |||||
| } | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // UI exporter class | // UI exporter class | ||||
| @@ -201,10 +219,14 @@ public: | |||||
| UIExporter(void* const ptr, const intptr_t winId, | UIExporter(void* const ptr, const intptr_t winId, | ||||
| const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const setSizeFunc setSizeCall, | const editParamFunc editParamCall, const setParamFunc setParamCall, const setStateFunc setStateCall, const sendNoteFunc sendNoteCall, const setSizeFunc setSizeCall, | ||||
| void* const dspPtr = nullptr) | void* const dspPtr = nullptr) | ||||
| #ifdef HAVE_DGL | |||||
| : glApp(), | : glApp(), | ||||
| glWindow(glApp, winId, dspPtr), | glWindow(glApp, winId, dspPtr), | ||||
| fChangingSize(false), | fChangingSize(false), | ||||
| fUI(glWindow.getUI()), | fUI(glWindow.getUI()), | ||||
| #else | |||||
| : fUI(createUiWrapper(dspPtr, winId)), | |||||
| #endif | |||||
| fData((fUI != nullptr) ? fUI->pData : nullptr) | fData((fUI != nullptr) ? fUI->pData : nullptr) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | ||||
| @@ -222,24 +244,43 @@ public: | |||||
| uint getWidth() const noexcept | uint getWidth() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getWidth(); | return glWindow.getWidth(); | ||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | |||||
| return fUI->getWidth(); | |||||
| #endif | |||||
| } | } | ||||
| uint getHeight() const noexcept | uint getHeight() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getHeight(); | return glWindow.getHeight(); | ||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, 1); | |||||
| return fUI->getHeight(); | |||||
| #endif | |||||
| } | } | ||||
| bool isVisible() const noexcept | bool isVisible() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.isVisible(); | return glWindow.isVisible(); | ||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | |||||
| return fUI->isRunning(); | |||||
| #endif | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| intptr_t getWindowId() const noexcept | intptr_t getWindowId() const noexcept | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| return glWindow.getWindowId(); | return glWindow.getWindowId(); | ||||
| #else | |||||
| return 0; | |||||
| #endif | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -282,6 +323,7 @@ public: | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #ifdef HAVE_DGL | |||||
| void exec(IdleCallback* const cb) | void exec(IdleCallback* const cb) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | ||||
| @@ -297,27 +339,48 @@ public: | |||||
| if (glWindow.isReady()) | if (glWindow.isReady()) | ||||
| fUI->uiIdle(); | fUI->uiIdle(); | ||||
| } | } | ||||
| #endif | |||||
| bool idle() | bool idle() | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr, false); | ||||
| #ifdef HAVE_DGL | |||||
| glApp.idle(); | glApp.idle(); | ||||
| if (glWindow.isReady()) | if (glWindow.isReady()) | ||||
| fUI->uiIdle(); | fUI->uiIdle(); | ||||
| return ! glApp.isQuiting(); | return ! glApp.isQuiting(); | ||||
| #else | |||||
| return fUI->isRunning(); | |||||
| #endif | |||||
| } | } | ||||
| void quit() | void quit() | ||||
| { | { | ||||
| #ifdef HAVE_DGL | |||||
| glWindow.close(); | glWindow.close(); | ||||
| glApp.quit(); | glApp.quit(); | ||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->terminateAndWaitForProcess(); | |||||
| #endif | |||||
| } | } | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| void setWindowTitle(const char* const uiTitle) | |||||
| { | |||||
| #ifdef HAVE_DGL | |||||
| glWindow.setTitle(uiTitle); | |||||
| #else | |||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | |||||
| fUI->setTitle(uiTitle); | |||||
| #endif | |||||
| } | |||||
| #ifdef HAVE_DGL | |||||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) | void setWindowSize(const uint width, const uint height, const bool updateUI = false) | ||||
| { | { | ||||
| DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | DISTRHO_SAFE_ASSERT_RETURN(fUI != nullptr,); | ||||
| @@ -333,11 +396,6 @@ public: | |||||
| fChangingSize = false; | fChangingSize = false; | ||||
| } | } | ||||
| void setWindowTitle(const char* const uiTitle) | |||||
| { | |||||
| glWindow.setTitle(uiTitle); | |||||
| } | |||||
| void setWindowTransientWinId(const uintptr_t winId) | void setWindowTransientWinId(const uintptr_t winId) | ||||
| { | { | ||||
| glWindow.setTransientWinId(winId); | glWindow.setTransientWinId(winId); | ||||
| @@ -349,6 +407,11 @@ public: | |||||
| return ! glApp.isQuiting(); | return ! glApp.isQuiting(); | ||||
| } | } | ||||
| #else | |||||
| void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | |||||
| void setWindowTransientWinId(const uintptr_t winId) {} | |||||
| bool setWindowVisible(const bool yesNo) { return true; } | |||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -368,6 +431,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| #ifdef HAVE_DGL | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // DGL Application and Window for this widget | // DGL Application and Window for this widget | ||||
| @@ -376,6 +440,7 @@ private: | |||||
| // prevent recursion | // prevent recursion | ||||
| bool fChangingSize; | bool fChangingSize; | ||||
| #endif | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| // Widget and DistrhoUI data | // Widget and DistrhoUI data | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * DISTRHO Plugin Framework (DPF) | * DISTRHO Plugin Framework (DPF) | ||||
| * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||||
| * | * | ||||
| * Permission to use, copy, modify, and/or distribute this software for any purpose with | * Permission to use, copy, modify, and/or distribute this software for any purpose with | ||||
| * or without fee is hereby granted, provided that the above copyright notice and this | * or without fee is hereby granted, provided that the above copyright notice and this | ||||
| @@ -29,17 +29,6 @@ namespace FloatVectorHelpers | |||||
| #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); | #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); | ||||
| #if JUCE_USE_SSE_INTRINSICS | #if JUCE_USE_SSE_INTRINSICS | ||||
| static bool sse2Present = false; | |||||
| static bool isSSE2Available() noexcept | |||||
| { | |||||
| if (sse2Present) | |||||
| return true; | |||||
| sse2Present = SystemStats::hasSSE2(); | |||||
| return sse2Present; | |||||
| } | |||||
| inline static bool isAligned (const void* p) noexcept | inline static bool isAligned (const void* p) noexcept | ||||
| { | { | ||||
| return (((pointer_sized_int) p) & 15) == 0; | return (((pointer_sized_int) p) & 15) == 0; | ||||
| @@ -113,7 +102,6 @@ namespace FloatVectorHelpers | |||||
| #define JUCE_BEGIN_VEC_OP \ | #define JUCE_BEGIN_VEC_OP \ | ||||
| typedef FloatVectorHelpers::ModeType<sizeof(*dest)>::Mode Mode; \ | typedef FloatVectorHelpers::ModeType<sizeof(*dest)>::Mode Mode; \ | ||||
| if (FloatVectorHelpers::isSSE2Available()) \ | |||||
| { \ | { \ | ||||
| const int numLongOps = num / Mode::numParallel; | const int numLongOps = num / Mode::numParallel; | ||||
| @@ -372,11 +360,7 @@ namespace FloatVectorHelpers | |||||
| { | { | ||||
| int numLongOps = num / Mode::numParallel; | int numLongOps = num / Mode::numParallel; | ||||
| #if JUCE_USE_SSE_INTRINSICS | |||||
| if (numLongOps > 1 && isSSE2Available()) | |||||
| #else | |||||
| if (numLongOps > 1) | if (numLongOps > 1) | ||||
| #endif | |||||
| { | { | ||||
| ParallelType val; | ParallelType val; | ||||
| @@ -446,11 +430,7 @@ namespace FloatVectorHelpers | |||||
| { | { | ||||
| int numLongOps = num / Mode::numParallel; | int numLongOps = num / Mode::numParallel; | ||||
| #if JUCE_USE_SSE_INTRINSICS | |||||
| if (numLongOps > 1 && isSSE2Available()) | |||||
| #else | |||||
| if (numLongOps > 1) | if (numLongOps > 1) | ||||
| #endif | |||||
| { | { | ||||
| ParallelType mn, mx; | ParallelType mn, mx; | ||||
| @@ -999,15 +979,24 @@ double JUCE_CALLTYPE FloatVectorOperations::findMaximum (const double* src, int | |||||
| #endif | #endif | ||||
| } | } | ||||
| #if ! JUCE_MINGW | |||||
| void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept | void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept | ||||
| { | { | ||||
| #if JUCE_USE_SSE_INTRINSICS | #if JUCE_USE_SSE_INTRINSICS | ||||
| if (FloatVectorHelpers::isSSE2Available()) | |||||
| _MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF); | |||||
| _MM_SET_FLUSH_ZERO_MODE (shouldEnable ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF); | |||||
| #endif | #endif | ||||
| ignoreUnused (shouldEnable); | ignoreUnused (shouldEnable); | ||||
| } | } | ||||
| void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport() noexcept | |||||
| { | |||||
| #if JUCE_USE_SSE_INTRINSICS | |||||
| const int mxcsr = _mm_getcsr(); | |||||
| _mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits | |||||
| #endif | |||||
| } | |||||
| #endif | |||||
| //============================================================================== | //============================================================================== | ||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_UNIT_TESTS | #if JUCE_UNIT_TESTS | ||||
| @@ -198,6 +198,12 @@ public: | |||||
| Effectively, this is a wrapper around a call to _MM_SET_FLUSH_ZERO_MODE | Effectively, this is a wrapper around a call to _MM_SET_FLUSH_ZERO_MODE | ||||
| */ | */ | ||||
| static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; | static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; | ||||
| /** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes. | |||||
| This effectively sets the DAZ and FZ bits of the MXCSR register. It's a convenient thing to | |||||
| call before audio processing code where you really want to avoid denormalisation performance hits. | |||||
| */ | |||||
| static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept; | |||||
| }; | }; | ||||
| @@ -0,0 +1,63 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2015 - ROLI Ltd. | |||||
| Permission is granted to use this software under the terms of either: | |||||
| a) the GPL v2 (or any later version) | |||||
| b) the Affero GPL v3 | |||||
| Details of these licenses can be found at: www.gnu.org/licenses | |||||
| JUCE 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. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.juce.com for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| struct CatmullRomAlgorithm | |||||
| { | |||||
| static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept | |||||
| { | |||||
| const float y0 = inputs[3]; | |||||
| const float y1 = inputs[2]; | |||||
| const float y2 = inputs[1]; | |||||
| const float y3 = inputs[0]; | |||||
| const float halfY0 = 0.5f * y0; | |||||
| const float halfY3 = 0.5f * y3; | |||||
| return y1 + offset * ((0.5f * y2 - halfY0) | |||||
| + (offset * (((y0 + 2.0f * y2) - (halfY3 + 2.5f * y1)) | |||||
| + (offset * ((halfY3 + 1.5f * y1) - (halfY0 + 1.5f * y2)))))); | |||||
| } | |||||
| }; | |||||
| CatmullRomInterpolator::CatmullRomInterpolator() noexcept { reset(); } | |||||
| CatmullRomInterpolator::~CatmullRomInterpolator() noexcept {} | |||||
| void CatmullRomInterpolator::reset() noexcept | |||||
| { | |||||
| subSamplePos = 1.0; | |||||
| for (int i = 0; i < numElementsInArray (lastInputSamples); ++i) | |||||
| lastInputSamples[i] = 0; | |||||
| } | |||||
| int CatmullRomInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept | |||||
| { | |||||
| return interpolate<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); | |||||
| } | |||||
| int CatmullRomInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept | |||||
| { | |||||
| return interpolateAdding<CatmullRomAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); | |||||
| } | |||||
| @@ -0,0 +1,89 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library. | |||||
| Copyright (c) 2015 - ROLI Ltd. | |||||
| Permission is granted to use this software under the terms of either: | |||||
| a) the GPL v2 (or any later version) | |||||
| b) the Affero GPL v3 | |||||
| Details of these licenses can be found at: www.gnu.org/licenses | |||||
| JUCE 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. | |||||
| ------------------------------------------------------------------------------ | |||||
| To release a closed-source product which uses JUCE, commercial licenses are | |||||
| available: visit www.juce.com for more information. | |||||
| ============================================================================== | |||||
| */ | |||||
| /** | |||||
| Interpolator for resampling a stream of floats using Catmull-Rom interpolation. | |||||
| Note that the resampler is stateful, so when there's a break in the continuity | |||||
| of the input stream you're feeding it, you should call reset() before feeding | |||||
| it any new data. And like with any other stateful filter, if you're resampling | |||||
| multiple channels, make sure each one uses its own CatmullRomInterpolator | |||||
| object. | |||||
| @see LagrangeInterpolator | |||||
| */ | |||||
| class JUCE_API CatmullRomInterpolator | |||||
| { | |||||
| public: | |||||
| CatmullRomInterpolator() noexcept; | |||||
| ~CatmullRomInterpolator() noexcept; | |||||
| /** Resets the state of the interpolator. | |||||
| Call this when there's a break in the continuity of the input data stream. | |||||
| */ | |||||
| void reset() noexcept; | |||||
| /** Resamples a stream of samples. | |||||
| @param speedRatio the number of input samples to use for each output sample | |||||
| @param inputSamples the source data to read from. This must contain at | |||||
| least (speedRatio * numOutputSamplesToProduce) samples. | |||||
| @param outputSamples the buffer to write the results into | |||||
| @param numOutputSamplesToProduce the number of output samples that should be created | |||||
| @returns the actual number of input samples that were used | |||||
| */ | |||||
| int process (double speedRatio, | |||||
| const float* inputSamples, | |||||
| float* outputSamples, | |||||
| int numOutputSamplesToProduce) noexcept; | |||||
| /** Resamples a stream of samples, adding the results to the output data | |||||
| with a gain. | |||||
| @param speedRatio the number of input samples to use for each output sample | |||||
| @param inputSamples the source data to read from. This must contain at | |||||
| least (speedRatio * numOutputSamplesToProduce) samples. | |||||
| @param outputSamples the buffer to write the results to - the result values will be added | |||||
| to any pre-existing data in this buffer after being multiplied by | |||||
| the gain factor | |||||
| @param numOutputSamplesToProduce the number of output samples that should be created | |||||
| @param gain a gain factor to multiply the resulting samples by before | |||||
| adding them to the destination buffer | |||||
| @returns the actual number of input samples that were used | |||||
| */ | |||||
| int processAdding (double speedRatio, | |||||
| const float* inputSamples, | |||||
| float* outputSamples, | |||||
| int numOutputSamplesToProduce, | |||||
| float gain) noexcept; | |||||
| private: | |||||
| float lastInputSamples[5]; | |||||
| double subSamplePos; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CatmullRomInterpolator) | |||||
| }; | |||||
| @@ -22,185 +22,179 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| namespace LagrangeHelpers | |||||
| namespace | |||||
| { | { | ||||
| template <int k> | |||||
| struct ResampleHelper | |||||
| { | |||||
| static forcedinline void calc (float& a, float b) { a *= b * (1.0f / k); } | |||||
| }; | |||||
| template<> | |||||
| struct ResampleHelper <0> | |||||
| { | |||||
| static forcedinline void calc (float&, float) {} | |||||
| }; | |||||
| template <int k> | |||||
| static forcedinline float calcCoefficient (float input, const float offset) noexcept | |||||
| static forcedinline void pushInterpolationSample (float* lastInputSamples, const float newValue) noexcept | |||||
| { | { | ||||
| ResampleHelper <0 - k>::calc (input, -2.0f - offset); | |||||
| ResampleHelper <1 - k>::calc (input, -1.0f - offset); | |||||
| ResampleHelper <2 - k>::calc (input, 0.0f - offset); | |||||
| ResampleHelper <3 - k>::calc (input, 1.0f - offset); | |||||
| ResampleHelper <4 - k>::calc (input, 2.0f - offset); | |||||
| return input; | |||||
| lastInputSamples[4] = lastInputSamples[3]; | |||||
| lastInputSamples[3] = lastInputSamples[2]; | |||||
| lastInputSamples[2] = lastInputSamples[1]; | |||||
| lastInputSamples[1] = lastInputSamples[0]; | |||||
| lastInputSamples[0] = newValue; | |||||
| } | } | ||||
| static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept | |||||
| { | |||||
| return calcCoefficient<0> (inputs[4], offset) | |||||
| + calcCoefficient<1> (inputs[3], offset) | |||||
| + calcCoefficient<2> (inputs[2], offset) | |||||
| + calcCoefficient<3> (inputs[1], offset) | |||||
| + calcCoefficient<4> (inputs[0], offset); | |||||
| } | |||||
| static forcedinline void push (float* inputs, const float newValue) noexcept | |||||
| { | |||||
| inputs[4] = inputs[3]; | |||||
| inputs[3] = inputs[2]; | |||||
| inputs[2] = inputs[1]; | |||||
| inputs[1] = inputs[0]; | |||||
| inputs[0] = newValue; | |||||
| } | |||||
| } | |||||
| //============================================================================== | |||||
| LagrangeInterpolator::LagrangeInterpolator() { reset(); } | |||||
| LagrangeInterpolator::~LagrangeInterpolator() {} | |||||
| void LagrangeInterpolator::reset() noexcept | |||||
| { | |||||
| subSamplePos = 1.0; | |||||
| for (int i = 0; i < numElementsInArray (lastInputSamples); ++i) | |||||
| lastInputSamples[i] = 0; | |||||
| } | |||||
| int LagrangeInterpolator::process (const double actualRatio, const float* in, | |||||
| float* out, const int numOut) noexcept | |||||
| { | |||||
| if (actualRatio == 1.0) | |||||
| static forcedinline void pushInterpolationSamples (float* lastInputSamples, const float* input, int numOut) noexcept | |||||
| { | { | ||||
| memcpy (out, in, (size_t) numOut * sizeof (float)); | |||||
| if (numOut >= 4) | |||||
| if (numOut >= 5) | |||||
| { | { | ||||
| const float* end = in + numOut; | |||||
| for (int i = 0; i < 4; ++i) | |||||
| lastInputSamples[i] = *--end; | |||||
| for (int i = 0; i < 5; ++i) | |||||
| lastInputSamples[i] = input[--numOut]; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| for (int i = 0; i < numOut; ++i) | for (int i = 0; i < numOut; ++i) | ||||
| LagrangeHelpers::push (lastInputSamples, in[i]); | |||||
| pushInterpolationSample (lastInputSamples, input[i]); | |||||
| } | } | ||||
| return numOut; | |||||
| } | } | ||||
| const float* const originalIn = in; | |||||
| double pos = subSamplePos; | |||||
| if (actualRatio < 1.0) | |||||
| template <typename InterpolatorType> | |||||
| static int interpolate (float* lastInputSamples, double& subSamplePos, const double actualRatio, | |||||
| const float* in, float* out, const int numOut) noexcept | |||||
| { | { | ||||
| for (int i = numOut; --i >= 0;) | |||||
| if (actualRatio == 1.0) | |||||
| { | { | ||||
| if (pos >= 1.0) | |||||
| memcpy (out, in, (size_t) numOut * sizeof (float)); | |||||
| pushInterpolationSamples (lastInputSamples, in, numOut); | |||||
| return numOut; | |||||
| } | |||||
| const float* const originalIn = in; | |||||
| double pos = subSamplePos; | |||||
| if (actualRatio < 1.0) | |||||
| { | |||||
| for (int i = numOut; --i >= 0;) | |||||
| { | { | ||||
| LagrangeHelpers::push (lastInputSamples, *in++); | |||||
| pos -= 1.0; | |||||
| if (pos >= 1.0) | |||||
| { | |||||
| pushInterpolationSample (lastInputSamples, *in++); | |||||
| pos -= 1.0; | |||||
| } | |||||
| *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); | |||||
| pos += actualRatio; | |||||
| } | } | ||||
| *out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos); | |||||
| pos += actualRatio; | |||||
| } | } | ||||
| } | |||||
| else | |||||
| { | |||||
| for (int i = numOut; --i >= 0;) | |||||
| else | |||||
| { | { | ||||
| while (pos < actualRatio) | |||||
| for (int i = numOut; --i >= 0;) | |||||
| { | { | ||||
| LagrangeHelpers::push (lastInputSamples, *in++); | |||||
| pos += 1.0; | |||||
| while (pos < actualRatio) | |||||
| { | |||||
| pushInterpolationSample (lastInputSamples, *in++); | |||||
| pos += 1.0; | |||||
| } | |||||
| pos -= actualRatio; | |||||
| *out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); | |||||
| } | } | ||||
| pos -= actualRatio; | |||||
| *out++ = LagrangeHelpers::valueAtOffset (lastInputSamples, 1.0f - (float) pos); | |||||
| } | } | ||||
| } | |||||
| subSamplePos = pos; | |||||
| return (int) (in - originalIn); | |||||
| } | |||||
| subSamplePos = pos; | |||||
| return (int) (in - originalIn); | |||||
| } | |||||
| int LagrangeInterpolator::processAdding (const double actualRatio, const float* in, | |||||
| float* out, const int numOut, const float gain) noexcept | |||||
| { | |||||
| if (actualRatio == 1.0) | |||||
| template <typename InterpolatorType> | |||||
| static int interpolateAdding (float* lastInputSamples, double& subSamplePos, const double actualRatio, | |||||
| const float* in, float* out, const int numOut, const float gain) noexcept | |||||
| { | { | ||||
| if (gain != 1.0f) | |||||
| { | |||||
| for (int i = 0; i < numOut; ++i) | |||||
| out[i] += in[i] * gain; | |||||
| } | |||||
| else | |||||
| if (actualRatio == 1.0) | |||||
| { | { | ||||
| for (int i = 0; i < numOut; ++i) | |||||
| out[i] += in[i]; | |||||
| FloatVectorOperations::addWithMultiply (out, in, gain, numOut); | |||||
| pushInterpolationSamples (lastInputSamples, in, numOut); | |||||
| return numOut; | |||||
| } | } | ||||
| if (numOut >= 4) | |||||
| { | |||||
| const float* end = in + numOut; | |||||
| const float* const originalIn = in; | |||||
| double pos = subSamplePos; | |||||
| for (int i = 0; i < 4; ++i) | |||||
| lastInputSamples[i] = *--end; | |||||
| if (actualRatio < 1.0) | |||||
| { | |||||
| for (int i = numOut; --i >= 0;) | |||||
| { | |||||
| if (pos >= 1.0) | |||||
| { | |||||
| pushInterpolationSample (lastInputSamples, *in++); | |||||
| pos -= 1.0; | |||||
| } | |||||
| *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (float) pos); | |||||
| pos += actualRatio; | |||||
| } | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| for (int i = 0; i < numOut; ++i) | |||||
| LagrangeHelpers::push (lastInputSamples, in[i]); | |||||
| for (int i = numOut; --i >= 0;) | |||||
| { | |||||
| while (pos < actualRatio) | |||||
| { | |||||
| pushInterpolationSample (lastInputSamples, *in++); | |||||
| pos += 1.0; | |||||
| } | |||||
| pos -= actualRatio; | |||||
| *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); | |||||
| } | |||||
| } | } | ||||
| return numOut; | |||||
| subSamplePos = pos; | |||||
| return (int) (in - originalIn); | |||||
| } | } | ||||
| } | |||||
| const float* const originalIn = in; | |||||
| double pos = subSamplePos; | |||||
| //============================================================================== | |||||
| template <int k> | |||||
| struct LagrangeResampleHelper | |||||
| { | |||||
| static forcedinline void calc (float& a, float b) noexcept { a *= b * (1.0f / k); } | |||||
| }; | |||||
| if (actualRatio < 1.0) | |||||
| { | |||||
| for (int i = numOut; --i >= 0;) | |||||
| { | |||||
| if (pos >= 1.0) | |||||
| { | |||||
| LagrangeHelpers::push (lastInputSamples, *in++); | |||||
| pos -= 1.0; | |||||
| } | |||||
| template<> | |||||
| struct LagrangeResampleHelper<0> | |||||
| { | |||||
| static forcedinline void calc (float&, float) noexcept {} | |||||
| }; | |||||
| *out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, (float) pos); | |||||
| pos += actualRatio; | |||||
| } | |||||
| } | |||||
| else | |||||
| struct LagrangeAlgorithm | |||||
| { | |||||
| static forcedinline float valueAtOffset (const float* const inputs, const float offset) noexcept | |||||
| { | { | ||||
| for (int i = numOut; --i >= 0;) | |||||
| { | |||||
| while (pos < actualRatio) | |||||
| { | |||||
| LagrangeHelpers::push (lastInputSamples, *in++); | |||||
| pos += 1.0; | |||||
| } | |||||
| return calcCoefficient<0> (inputs[4], offset) | |||||
| + calcCoefficient<1> (inputs[3], offset) | |||||
| + calcCoefficient<2> (inputs[2], offset) | |||||
| + calcCoefficient<3> (inputs[1], offset) | |||||
| + calcCoefficient<4> (inputs[0], offset); | |||||
| } | |||||
| pos -= actualRatio; | |||||
| *out++ += gain * LagrangeHelpers::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (float) pos)); | |||||
| } | |||||
| template <int k> | |||||
| static forcedinline float calcCoefficient (float input, const float offset) noexcept | |||||
| { | |||||
| LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset); | |||||
| LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset); | |||||
| LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset); | |||||
| LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset); | |||||
| LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset); | |||||
| return input; | |||||
| } | } | ||||
| }; | |||||
| LagrangeInterpolator::LagrangeInterpolator() noexcept { reset(); } | |||||
| LagrangeInterpolator::~LagrangeInterpolator() noexcept {} | |||||
| subSamplePos = pos; | |||||
| return (int) (in - originalIn); | |||||
| void LagrangeInterpolator::reset() noexcept | |||||
| { | |||||
| subSamplePos = 1.0; | |||||
| for (int i = 0; i < numElementsInArray (lastInputSamples); ++i) | |||||
| lastInputSamples[i] = 0; | |||||
| } | |||||
| int LagrangeInterpolator::process (double actualRatio, const float* in, float* out, int numOut) noexcept | |||||
| { | |||||
| return interpolate<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut); | |||||
| } | |||||
| int LagrangeInterpolator::processAdding (double actualRatio, const float* in, float* out, int numOut, float gain) noexcept | |||||
| { | |||||
| return interpolateAdding<LagrangeAlgorithm> (lastInputSamples, subSamplePos, actualRatio, in, out, numOut, gain); | |||||
| } | } | ||||
| @@ -22,11 +22,7 @@ | |||||
| ============================================================================== | ============================================================================== | ||||
| */ | */ | ||||
| #ifndef JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED | |||||
| #define JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED | |||||
| //============================================================================== | |||||
| /** | /** | ||||
| Interpolator for resampling a stream of floats using 4-point lagrange interpolation. | Interpolator for resampling a stream of floats using 4-point lagrange interpolation. | ||||
| @@ -35,12 +31,14 @@ | |||||
| it any new data. And like with any other stateful filter, if you're resampling | it any new data. And like with any other stateful filter, if you're resampling | ||||
| multiple channels, make sure each one uses its own LagrangeInterpolator | multiple channels, make sure each one uses its own LagrangeInterpolator | ||||
| object. | object. | ||||
| @see CatmullRomInterpolator | |||||
| */ | */ | ||||
| class JUCE_API LagrangeInterpolator | class JUCE_API LagrangeInterpolator | ||||
| { | { | ||||
| public: | public: | ||||
| LagrangeInterpolator(); | |||||
| ~LagrangeInterpolator(); | |||||
| LagrangeInterpolator() noexcept; | |||||
| ~LagrangeInterpolator() noexcept; | |||||
| /** Resets the state of the interpolator. | /** Resets the state of the interpolator. | ||||
| Call this when there's a break in the continuity of the input data stream. | Call this when there's a break in the continuity of the input data stream. | ||||
| @@ -89,6 +87,3 @@ private: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LagrangeInterpolator) | ||||
| }; | }; | ||||
| #endif // JUCE_LAGRANGEINTERPOLATOR_H_INCLUDED | |||||
| @@ -49,7 +49,7 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Reset to a new sample rate and ramp length. */ | /** Reset to a new sample rate and ramp length. */ | ||||
| void reset (double sampleRate, double rampLengthInSeconds) noexcept | void reset (double sampleRate, double rampLengthInSeconds) noexcept | ||||
| { | { | ||||
| @@ -59,7 +59,7 @@ public: | |||||
| countdown = 0; | countdown = 0; | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Set a new target value. */ | /** Set a new target value. */ | ||||
| void setValue (FloatType newValue) noexcept | void setValue (FloatType newValue) noexcept | ||||
| { | { | ||||
| @@ -75,7 +75,7 @@ public: | |||||
| } | } | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Compute the next value. */ | /** Compute the next value. */ | ||||
| FloatType getNextValue() noexcept | FloatType getNextValue() noexcept | ||||
| { | { | ||||
| @@ -88,7 +88,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| FloatType currentValue, target, step; | FloatType currentValue, target, step; | ||||
| int countdown, stepsToTarget; | int countdown, stepsToTarget; | ||||
| }; | }; | ||||
| @@ -58,9 +58,7 @@ | |||||
| #endif | #endif | ||||
| #if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK | #if (JUCE_MAC || JUCE_IOS) && JUCE_USE_VDSP_FRAMEWORK | ||||
| #define Point CarbonDummyPointName // (workaround to avoid definition of "Point" by old Carbon headers) | |||||
| #include <Accelerate/Accelerate.h> | #include <Accelerate/Accelerate.h> | ||||
| #undef Point | |||||
| #else | #else | ||||
| #undef JUCE_USE_VDSP_FRAMEWORK | #undef JUCE_USE_VDSP_FRAMEWORK | ||||
| #endif | #endif | ||||
| @@ -81,6 +79,7 @@ namespace juce | |||||
| #include "effects/juce_IIRFilter.cpp" | #include "effects/juce_IIRFilter.cpp" | ||||
| #include "effects/juce_IIRFilterOld.cpp" | #include "effects/juce_IIRFilterOld.cpp" | ||||
| #include "effects/juce_LagrangeInterpolator.cpp" | #include "effects/juce_LagrangeInterpolator.cpp" | ||||
| #include "effects/juce_CatmullRomInterpolator.cpp" | |||||
| #include "effects/juce_FFT.cpp" | #include "effects/juce_FFT.cpp" | ||||
| #include "midi/juce_MidiBuffer.cpp" | #include "midi/juce_MidiBuffer.cpp" | ||||
| #include "midi/juce_MidiFile.cpp" | #include "midi/juce_MidiFile.cpp" | ||||
| @@ -27,7 +27,7 @@ | |||||
| #include "../juce_core/juce_core.h" | #include "../juce_core/juce_core.h" | ||||
| //============================================================================= | |||||
| //============================================================================== | |||||
| namespace juce | namespace juce | ||||
| { | { | ||||
| @@ -41,6 +41,7 @@ namespace juce | |||||
| #include "effects/juce_IIRFilter.h" | #include "effects/juce_IIRFilter.h" | ||||
| #include "effects/juce_IIRFilterOld.h" | #include "effects/juce_IIRFilterOld.h" | ||||
| #include "effects/juce_LagrangeInterpolator.h" | #include "effects/juce_LagrangeInterpolator.h" | ||||
| #include "effects/juce_CatmullRomInterpolator.h" | |||||
| #include "effects/juce_FFT.h" | #include "effects/juce_FFT.h" | ||||
| #include "effects/juce_LinearSmoothedValue.h" | #include "effects/juce_LinearSmoothedValue.h" | ||||
| #include "effects/juce_Reverb.h" | #include "effects/juce_Reverb.h" | ||||
| @@ -371,7 +371,7 @@ int MidiMessage::getNoteNumber() const noexcept | |||||
| void MidiMessage::setNoteNumber (const int newNoteNumber) noexcept | void MidiMessage::setNoteNumber (const int newNoteNumber) noexcept | ||||
| { | { | ||||
| if (isNoteOnOrOff()) | |||||
| if (isNoteOnOrOff() || isAftertouch()) | |||||
| getData()[1] = (uint8) (newNoteNumber & 127); | getData()[1] = (uint8) (newNoteNumber & 127); | ||||
| } | } | ||||
| @@ -156,23 +156,34 @@ struct MidiMessageSequenceSorter | |||||
| } | } | ||||
| }; | }; | ||||
| void MidiMessageSequence::addSequence (const MidiMessageSequence& other, double timeAdjustment) | |||||
| { | |||||
| for (int i = 0; i < other.list.size(); ++i) | |||||
| { | |||||
| const MidiMessage& m = other.list.getUnchecked(i)->message; | |||||
| MidiEventHolder* const newOne = new MidiEventHolder (m); | |||||
| newOne->message.addToTimeStamp (timeAdjustment); | |||||
| list.add (newOne); | |||||
| } | |||||
| sort(); | |||||
| } | |||||
| void MidiMessageSequence::addSequence (const MidiMessageSequence& other, | void MidiMessageSequence::addSequence (const MidiMessageSequence& other, | ||||
| double timeAdjustment, | double timeAdjustment, | ||||
| double firstAllowableTime, | double firstAllowableTime, | ||||
| double endOfAllowableDestTimes) | double endOfAllowableDestTimes) | ||||
| { | { | ||||
| firstAllowableTime -= timeAdjustment; | |||||
| endOfAllowableDestTimes -= timeAdjustment; | |||||
| for (int i = 0; i < other.list.size(); ++i) | for (int i = 0; i < other.list.size(); ++i) | ||||
| { | { | ||||
| const MidiMessage& m = other.list.getUnchecked(i)->message; | const MidiMessage& m = other.list.getUnchecked(i)->message; | ||||
| const double t = m.getTimeStamp(); | |||||
| const double t = m.getTimeStamp() + timeAdjustment; | |||||
| if (t >= firstAllowableTime && t < endOfAllowableDestTimes) | if (t >= firstAllowableTime && t < endOfAllowableDestTimes) | ||||
| { | { | ||||
| MidiEventHolder* const newOne = new MidiEventHolder (m); | MidiEventHolder* const newOne = new MidiEventHolder (m); | ||||
| newOne->message.setTimeStamp (timeAdjustment + t); | |||||
| newOne->message.setTimeStamp (t); | |||||
| list.add (newOne); | list.add (newOne); | ||||
| } | } | ||||
| @@ -160,7 +160,6 @@ public: | |||||
| void deleteEvent (int index, bool deleteMatchingNoteUp); | void deleteEvent (int index, bool deleteMatchingNoteUp); | ||||
| /** Merges another sequence into this one. | /** Merges another sequence into this one. | ||||
| Remember to call updateMatchedPairs() after using this method. | Remember to call updateMatchedPairs() after using this method. | ||||
| @param other the sequence to add from | @param other the sequence to add from | ||||
| @@ -178,6 +177,16 @@ public: | |||||
| double firstAllowableDestTime, | double firstAllowableDestTime, | ||||
| double endOfAllowableDestTimes); | double endOfAllowableDestTimes); | ||||
| /** Merges another sequence into this one. | |||||
| Remember to call updateMatchedPairs() after using this method. | |||||
| @param other the sequence to add from | |||||
| @param timeAdjustmentDelta an amount to add to the timestamps of the midi events | |||||
| as they are read from the other sequence | |||||
| */ | |||||
| void addSequence (const MidiMessageSequence& other, | |||||
| double timeAdjustmentDelta); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Makes sure all the note-on and note-off pairs are up-to-date. | /** Makes sure all the note-on and note-off pairs are up-to-date. | ||||
| @@ -331,7 +331,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectContainsRPN (const MidiBuffer& midiBuffer, | void expectContainsRPN (const MidiBuffer& midiBuffer, | ||||
| int channel, | int channel, | ||||
| int parameterNumber, | int parameterNumber, | ||||
| @@ -343,7 +343,7 @@ private: | |||||
| expectContainsRPN (midiBuffer, expected); | expectContainsRPN (midiBuffer, expected); | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectContainsRPN (const MidiBuffer& midiBuffer, MidiRPNMessage expected) | void expectContainsRPN (const MidiBuffer& midiBuffer, MidiRPNMessage expected) | ||||
| { | { | ||||
| MidiBuffer::Iterator iter (midiBuffer); | MidiBuffer::Iterator iter (midiBuffer); | ||||
| @@ -26,7 +26,7 @@ | |||||
| #define JUCE_MIDIRPNDETECTOR_H_INCLUDED | #define JUCE_MIDIRPNDETECTOR_H_INCLUDED | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered | /** Represents a MIDI RPN (registered parameter number) or NRPN (non-registered | ||||
| parameter number) message. | parameter number) message. | ||||
| */ | */ | ||||
| @@ -77,7 +77,7 @@ public: | |||||
| */ | */ | ||||
| void reset() noexcept; | void reset() noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Takes the next in a stream of incoming MIDI CC messages and returns true | /** Takes the next in a stream of incoming MIDI CC messages and returns true | ||||
| if it forms the last of a sequence that makes an RPN or NPRN. | if it forms the last of a sequence that makes an RPN or NPRN. | ||||
| @@ -91,7 +91,7 @@ public: | |||||
| MidiRPNMessage& result) noexcept; | MidiRPNMessage& result) noexcept; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| struct ChannelState | struct ChannelState | ||||
| { | { | ||||
| ChannelState() noexcept; | ChannelState() noexcept; | ||||
| @@ -104,7 +104,7 @@ private: | |||||
| bool isNRPN; | bool isNRPN; | ||||
| }; | }; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| ChannelState states[16]; | ChannelState states[16]; | ||||
| JUCE_LEAK_DETECTOR (MidiRPNDetector) | JUCE_LEAK_DETECTOR (MidiRPNDetector) | ||||
| @@ -120,11 +120,11 @@ private: | |||||
| class JUCE_API MidiRPNGenerator | class JUCE_API MidiRPNGenerator | ||||
| { | { | ||||
| public: | public: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Generates a MIDI sequence representing the given RPN or NRPN message. */ | /** Generates a MIDI sequence representing the given RPN or NRPN message. */ | ||||
| static MidiBuffer generate (MidiRPNMessage message); | static MidiBuffer generate (MidiRPNMessage message); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Generates a MIDI sequence representing an RPN or NRPN message with the | /** Generates a MIDI sequence representing an RPN or NRPN message with the | ||||
| given parameters. | given parameters. | ||||
| @@ -135,14 +135,6 @@ void MPEInstrument::removeListener (Listener* const listenerToRemove) noexcept | |||||
| listeners.remove (listenerToRemove); | listeners.remove (listenerToRemove); | ||||
| } | } | ||||
| MPEInstrument::Listener::Listener() | |||||
| { | |||||
| } | |||||
| MPEInstrument::Listener::~Listener() | |||||
| { | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void MPEInstrument::processNextMidiEvent (const MidiMessage& message) | void MPEInstrument::processNextMidiEvent (const MidiMessage& message) | ||||
| { | { | ||||
| @@ -1976,7 +1968,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /* This mock class is used for unit testing whether the methods of | /* This mock class is used for unit testing whether the methods of | ||||
| MPEInstrument are called correctly. | MPEInstrument are called correctly. | ||||
| */ | */ | ||||
| @@ -2074,7 +2066,7 @@ private: | |||||
| ScopedPointer<MPENote> lastNoteFinished; | ScopedPointer<MPENote> lastNoteFinished; | ||||
| private: | private: | ||||
| //====================================================================== | |||||
| //============================================================================== | |||||
| void noteAdded (MPENote) override { noteAddedCallCounter++; } | void noteAdded (MPENote) override { noteAddedCallCounter++; } | ||||
| void notePressureChanged (MPENote) override { notePressureChangedCallCounter++; } | void notePressureChanged (MPENote) override { notePressureChangedCallCounter++; } | ||||
| @@ -2089,7 +2081,7 @@ private: | |||||
| } | } | ||||
| }; | }; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| template <int initial7BitPressure, int initial14BitPitchbend, int initial7BitTimbre> | template <int initial7BitPressure, int initial14BitPitchbend, int initial7BitTimbre> | ||||
| class CustomInitialValuesTest : public MPEInstrument | class CustomInitialValuesTest : public MPEInstrument | ||||
| { | { | ||||
| @@ -2109,7 +2101,7 @@ private: | |||||
| } | } | ||||
| }; | }; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectNote (MPENote noteToTest, | void expectNote (MPENote noteToTest, | ||||
| int noteOnVelocity7Bit, | int noteOnVelocity7Bit, | ||||
| int pressure7Bit, | int pressure7Bit, | ||||
| @@ -2141,7 +2133,7 @@ private: | |||||
| expect (std::fabs (expected - actual) < maxAbsoluteError); | expect (std::fabs (expected - actual) < maxAbsoluteError); | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| MPEZoneLayout testLayout; | MPEZoneLayout testLayout; | ||||
| }; | }; | ||||
| @@ -68,7 +68,7 @@ public: | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| virtual ~MPEInstrument(); | virtual ~MPEInstrument(); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Returns the current zone layout of the instrument. | /** Returns the current zone layout of the instrument. | ||||
| This happens by value, to enforce thread-safety and class invariants. | This happens by value, to enforce thread-safety and class invariants. | ||||
| @@ -98,7 +98,7 @@ public: | |||||
| */ | */ | ||||
| bool isMasterChannel (int midiChannel) const noexcept; | bool isMasterChannel (int midiChannel) const noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** The MPE note tracking mode. In case there is more than one note playing | /** The MPE note tracking mode. In case there is more than one note playing | ||||
| simultaneously on the same MIDI channel, this determines which of these | simultaneously on the same MIDI channel, this determines which of these | ||||
| notes will be modulated by an incoming MPE message on that channel | notes will be modulated by an incoming MPE message on that channel | ||||
| @@ -123,7 +123,7 @@ public: | |||||
| /** Set the MPE tracking mode for the timbre dimension. */ | /** Set the MPE tracking mode for the timbre dimension. */ | ||||
| void setTimbreTrackingMode (TrackingMode modeToUse); | void setTimbreTrackingMode (TrackingMode modeToUse); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Process a MIDI message and trigger the appropriate method calls | /** Process a MIDI message and trigger the appropriate method calls | ||||
| (noteOn, noteOff etc.) | (noteOn, noteOff etc.) | ||||
| @@ -132,7 +132,7 @@ public: | |||||
| */ | */ | ||||
| virtual void processNextMidiEvent (const MidiMessage& message); | virtual void processNextMidiEvent (const MidiMessage& message); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Request a note-on on the given channel, with the given initial note | /** Request a note-on on the given channel, with the given initial note | ||||
| number and velocity. | number and velocity. | ||||
| If the message arrives on a valid note channel, this will create a | If the message arrives on a valid note channel, this will create a | ||||
| @@ -187,7 +187,7 @@ public: | |||||
| */ | */ | ||||
| void releaseAllNotes(); | void releaseAllNotes(); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Returns the number of MPE notes currently played by the | /** Returns the number of MPE notes currently played by the | ||||
| instrument. | instrument. | ||||
| */ | */ | ||||
| @@ -221,7 +221,7 @@ public: | |||||
| */ | */ | ||||
| MPENote getMostRecentNoteOtherThan (MPENote otherThanThisNote) const noexcept; | MPENote getMostRecentNoteOtherThan (MPENote otherThanThisNote) const noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Derive from this class to be informed about any changes in the expressive | /** Derive from this class to be informed about any changes in the expressive | ||||
| MIDI notes played by this instrument. | MIDI notes played by this instrument. | ||||
| @@ -230,14 +230,11 @@ public: | |||||
| Therefore you should never do heavy work such as graphics rendering etc. | Therefore you should never do heavy work such as graphics rendering etc. | ||||
| inside those callbacks. | inside those callbacks. | ||||
| */ | */ | ||||
| class Listener | |||||
| class JUCE_API Listener | |||||
| { | { | ||||
| public: | public: | ||||
| /** Constructor. */ | |||||
| Listener(); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| virtual ~Listener(); | |||||
| virtual ~Listener() {} | |||||
| /** Implement this callback to be informed whenever a new expressive | /** Implement this callback to be informed whenever a new expressive | ||||
| MIDI note is triggered. | MIDI note is triggered. | ||||
| @@ -278,14 +275,14 @@ public: | |||||
| virtual void noteReleased (MPENote finishedNote) = 0; | virtual void noteReleased (MPENote finishedNote) = 0; | ||||
| }; | }; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Adds a listener. */ | /** Adds a listener. */ | ||||
| void addListener (Listener* const listenerToAdd) noexcept; | |||||
| void addListener (Listener* listenerToAdd) noexcept; | |||||
| /** Removes a listener. */ | /** Removes a listener. */ | ||||
| void removeListener (Listener* const listenerToRemove) noexcept; | |||||
| void removeListener (Listener* listenerToRemove) noexcept; | |||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Puts the instrument into legacy mode. | /** Puts the instrument into legacy mode. | ||||
| As a side effect, this will discard all currently playing notes, | As a side effect, this will discard all currently playing notes, | ||||
| and call noteReleased for all of them. | and call noteReleased for all of them. | ||||
| @@ -324,7 +321,7 @@ public: | |||||
| void setLegacyModePitchbendRange (int pitchbendRange); | void setLegacyModePitchbendRange (int pitchbendRange); | ||||
| protected: | protected: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** This method defines what initial pitchbend value should be used for newly | /** This method defines what initial pitchbend value should be used for newly | ||||
| triggered notes. The default is to use the last pitchbend value | triggered notes. The default is to use the last pitchbend value | ||||
| that has been received on the same MIDI channel (or no pitchbend | that has been received on the same MIDI channel (or no pitchbend | ||||
| @@ -354,7 +351,7 @@ protected: | |||||
| MPEValue midiNoteOnVelocity) const; | MPEValue midiNoteOnVelocity) const; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| CriticalSection lock; | CriticalSection lock; | ||||
| Array<MPENote> notes; | Array<MPENote> notes; | ||||
| MPEZoneLayout zoneLayout; | MPEZoneLayout zoneLayout; | ||||
| @@ -162,7 +162,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void testMidiBuffer (MidiBuffer& buffer, const uint8* expectedBytes, int expectedBytesSize) | void testMidiBuffer (MidiBuffer& buffer, const uint8* expectedBytes, int expectedBytesSize) | ||||
| { | { | ||||
| uint8 actualBytes[128] = { 0 }; | uint8 actualBytes[128] = { 0 }; | ||||
| @@ -171,7 +171,7 @@ private: | |||||
| expectEquals (std::memcmp (actualBytes, expectedBytes, (std::size_t) expectedBytesSize), 0); | expectEquals (std::memcmp (actualBytes, expectedBytes, (std::size_t) expectedBytesSize), 0); | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void extractRawBinaryData (const MidiBuffer& midiBuffer, const uint8* bufferToCopyTo, std::size_t maxBytes) | void extractRawBinaryData (const MidiBuffer& midiBuffer, const uint8* bufferToCopyTo, std::size_t maxBytes) | ||||
| { | { | ||||
| std::size_t pos = 0; | std::size_t pos = 0; | ||||
| @@ -103,7 +103,7 @@ class MPENoteTests : public UnitTest | |||||
| public: | public: | ||||
| MPENoteTests() : UnitTest ("MPENote class") {} | MPENoteTests() : UnitTest ("MPENote class") {} | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void runTest() override | void runTest() override | ||||
| { | { | ||||
| beginTest ("getFrequencyInHertz"); | beginTest ("getFrequencyInHertz"); | ||||
| @@ -116,7 +116,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectEqualsWithinOneCent (double frequencyInHertzActual, | void expectEqualsWithinOneCent (double frequencyInHertzActual, | ||||
| double frequencyInHertzExpected) | double frequencyInHertzExpected) | ||||
| { | { | ||||
| @@ -39,7 +39,7 @@ | |||||
| */ | */ | ||||
| struct JUCE_API MPENote | struct JUCE_API MPENote | ||||
| { | { | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| enum KeyState | enum KeyState | ||||
| { | { | ||||
| off = 0, | off = 0, | ||||
| @@ -48,7 +48,7 @@ struct JUCE_API MPENote | |||||
| keyDownAndSustained = 3 | keyDownAndSustained = 3 | ||||
| }; | }; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Constructor. | /** Constructor. | ||||
| @param midiChannel The MIDI channel of the note, between 2 and 16. | @param midiChannel The MIDI channel of the note, between 2 and 16. | ||||
| @@ -88,7 +88,7 @@ struct JUCE_API MPENote | |||||
| /** Checks whether the MPE note is valid. */ | /** Checks whether the MPE note is valid. */ | ||||
| bool isValid() const noexcept; | bool isValid() const noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| // Invariants that define the note. | // Invariants that define the note. | ||||
| /** A unique ID. Useful to distinguish the note from other simultaneously | /** A unique ID. Useful to distinguish the note from other simultaneously | ||||
| @@ -107,7 +107,7 @@ struct JUCE_API MPENote | |||||
| */ | */ | ||||
| uint8 initialNote; | uint8 initialNote; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| // The five dimensions of continuous expressive control | // The five dimensions of continuous expressive control | ||||
| /** The velocity ("strike") of the note-on. | /** The velocity ("strike") of the note-on. | ||||
| @@ -146,7 +146,7 @@ struct JUCE_API MPENote | |||||
| */ | */ | ||||
| MPEValue noteOffVelocity; | MPEValue noteOffVelocity; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Current effective pitchbend of the note in units of semitones, relative | /** Current effective pitchbend of the note in units of semitones, relative | ||||
| to initialNote. You should use this to compute the actual effective pitch | to initialNote. You should use this to compute the actual effective pitch | ||||
| of the note. This value is computed and set by an MPEInstrument to the | of the note. This value is computed and set by an MPEInstrument to the | ||||
| @@ -163,7 +163,7 @@ struct JUCE_API MPENote | |||||
| */ | */ | ||||
| KeyState keyState; | KeyState keyState; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Returns the current frequency of the note in Hertz. This is the a sum of | /** Returns the current frequency of the note in Hertz. This is the a sum of | ||||
| the initialNote and the totalPitchbendInSemitones, converted to Hertz. | the initialNote and the totalPitchbendInSemitones, converted to Hertz. | ||||
| */ | */ | ||||
| @@ -55,7 +55,7 @@ | |||||
| class JUCE_API MPESynthesiser : public MPESynthesiserBase | class JUCE_API MPESynthesiser : public MPESynthesiserBase | ||||
| { | { | ||||
| public: | public: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Constructor. | /** Constructor. | ||||
| You'll need to add some voices before it'll make any sound. | You'll need to add some voices before it'll make any sound. | ||||
| @@ -75,7 +75,7 @@ public: | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~MPESynthesiser(); | ~MPESynthesiser(); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Deletes all voices. */ | /** Deletes all voices. */ | ||||
| void clearVoices(); | void clearVoices(); | ||||
| @@ -116,7 +116,7 @@ public: | |||||
| */ | */ | ||||
| virtual void turnOffAllVoices (bool allowTailOff); | virtual void turnOffAllVoices (bool allowTailOff); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** If set to true, then the synth will try to take over an existing voice if | /** If set to true, then the synth will try to take over an existing voice if | ||||
| it runs out and needs to play another note. | it runs out and needs to play another note. | ||||
| @@ -128,7 +128,7 @@ public: | |||||
| /** Returns true if note-stealing is enabled. */ | /** Returns true if note-stealing is enabled. */ | ||||
| bool isVoiceStealingEnabled() const noexcept { return shouldStealVoices; } | bool isVoiceStealingEnabled() const noexcept { return shouldStealVoices; } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Tells the synthesiser what the sample rate is for the audio it's being used to render. | /** Tells the synthesiser what the sample rate is for the audio it's being used to render. | ||||
| This overrides the implementation in MPESynthesiserBase, to additionally | This overrides the implementation in MPESynthesiserBase, to additionally | ||||
| @@ -137,7 +137,7 @@ public: | |||||
| */ | */ | ||||
| void setCurrentPlaybackSampleRate (double newRate) override; | void setCurrentPlaybackSampleRate (double newRate) override; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Handle incoming MIDI events. | /** Handle incoming MIDI events. | ||||
| This method will be called automatically according to the MIDI data passed | This method will be called automatically according to the MIDI data passed | ||||
| @@ -238,7 +238,7 @@ protected: | |||||
| */ | */ | ||||
| virtual void noteKeyStateChanged (MPENote changedNote) override; | virtual void noteKeyStateChanged (MPENote changedNote) override; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** This will simply call renderNextBlock for each currently active | /** This will simply call renderNextBlock for each currently active | ||||
| voice and fill the buffer with the sum. | voice and fill the buffer with the sum. | ||||
| Override this method if you need to do more work to render your audio. | Override this method if you need to do more work to render your audio. | ||||
| @@ -255,7 +255,7 @@ protected: | |||||
| int startSample, | int startSample, | ||||
| int numSamples) override; | int numSamples) override; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Searches through the voices to find one that's not currently playing, and | /** Searches through the voices to find one that's not currently playing, and | ||||
| which can play the given MPE note. | which can play the given MPE note. | ||||
| @@ -298,11 +298,11 @@ protected: | |||||
| */ | */ | ||||
| void stopVoice (MPESynthesiserVoice* voice, MPENote noteToStop, bool allowTailOff); | void stopVoice (MPESynthesiserVoice* voice, MPENote noteToStop, bool allowTailOff); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| OwnedArray<MPESynthesiserVoice> voices; | OwnedArray<MPESynthesiserVoice> voices; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| bool shouldStealVoices; | bool shouldStealVoices; | ||||
| CriticalSection voicesLock; | CriticalSection voicesLock; | ||||
| @@ -47,7 +47,7 @@ | |||||
| struct JUCE_API MPESynthesiserBase : public MPEInstrument::Listener | struct JUCE_API MPESynthesiserBase : public MPEInstrument::Listener | ||||
| { | { | ||||
| public: | public: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Constructor. */ | /** Constructor. */ | ||||
| MPESynthesiserBase(); | MPESynthesiserBase(); | ||||
| @@ -61,7 +61,7 @@ public: | |||||
| */ | */ | ||||
| MPESynthesiserBase (MPEInstrument* instrument); | MPESynthesiserBase (MPEInstrument* instrument); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Returns the synthesiser's internal MPE zone layout. | /** Returns the synthesiser's internal MPE zone layout. | ||||
| This happens by value, to enforce thread-safety and class invariants. | This happens by value, to enforce thread-safety and class invariants. | ||||
| */ | */ | ||||
| @@ -73,7 +73,7 @@ public: | |||||
| */ | */ | ||||
| void setZoneLayout (MPEZoneLayout newLayout); | void setZoneLayout (MPEZoneLayout newLayout); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Tells the synthesiser what the sample rate is for the audio it's being | /** Tells the synthesiser what the sample rate is for the audio it's being | ||||
| used to render. | used to render. | ||||
| */ | */ | ||||
| @@ -84,7 +84,7 @@ public: | |||||
| */ | */ | ||||
| double getSampleRate() const noexcept { return sampleRate; } | double getSampleRate() const noexcept { return sampleRate; } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Creates the next block of audio output. | /** Creates the next block of audio output. | ||||
| Call this to make sound. This will chop up the AudioBuffer into subBlock | Call this to make sound. This will chop up the AudioBuffer into subBlock | ||||
| @@ -99,7 +99,7 @@ public: | |||||
| int startSample, | int startSample, | ||||
| int numSamples); | int numSamples); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Handle incoming MIDI events (called from renderNextBlock). | /** Handle incoming MIDI events (called from renderNextBlock). | ||||
| The default implementation provided here simply forwards everything | The default implementation provided here simply forwards everything | ||||
| @@ -113,7 +113,7 @@ public: | |||||
| */ | */ | ||||
| virtual void handleMidiEvent (const MidiMessage&); | virtual void handleMidiEvent (const MidiMessage&); | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering. | /** Sets a minimum limit on the size to which audio sub-blocks will be divided when rendering. | ||||
| When rendering, the audio blocks that are passed into renderNextBlock() will be split up | When rendering, the audio blocks that are passed into renderNextBlock() will be split up | ||||
| @@ -130,7 +130,7 @@ public: | |||||
| */ | */ | ||||
| void setMinimumRenderingSubdivisionSize (int numSamples) noexcept; | void setMinimumRenderingSubdivisionSize (int numSamples) noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Puts the synthesiser into legacy mode. | /** Puts the synthesiser into legacy mode. | ||||
| @param pitchbendRange The note pitchbend range in semitones to use when in legacy mode. | @param pitchbendRange The note pitchbend range in semitones to use when in legacy mode. | ||||
| @@ -160,7 +160,7 @@ public: | |||||
| void setLegacyModePitchbendRange (int pitchbendRange); | void setLegacyModePitchbendRange (int pitchbendRange); | ||||
| protected: | protected: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Implement this method to render your audio inside. | /** Implement this method to render your audio inside. | ||||
| @see renderNextBlock | @see renderNextBlock | ||||
| */ | */ | ||||
| @@ -176,14 +176,14 @@ protected: | |||||
| int /*numSamples*/) {} | int /*numSamples*/) {} | ||||
| protected: | protected: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** @internal */ | /** @internal */ | ||||
| ScopedPointer<MPEInstrument> instrument; | ScopedPointer<MPEInstrument> instrument; | ||||
| /** @internal */ | /** @internal */ | ||||
| CriticalSection renderAudioLock; | CriticalSection renderAudioLock; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| double sampleRate; | double sampleRate; | ||||
| int minimumSubBlockSize; | int minimumSubBlockSize; | ||||
| @@ -37,7 +37,7 @@ | |||||
| class JUCE_API MPESynthesiserVoice | class JUCE_API MPESynthesiserVoice | ||||
| { | { | ||||
| public: | public: | ||||
| //======================================================================== | |||||
| //============================================================================== | |||||
| /** Constructor. */ | /** Constructor. */ | ||||
| MPESynthesiserVoice(); | MPESynthesiserVoice(); | ||||
| @@ -160,7 +160,7 @@ public: | |||||
| bool wasStartedBefore (const MPESynthesiserVoice& other) const noexcept; | bool wasStartedBefore (const MPESynthesiserVoice& other) const noexcept; | ||||
| protected: | protected: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Resets the state of this voice after a sound has finished playing. | /** Resets the state of this voice after a sound has finished playing. | ||||
| The subclass must call this when it finishes playing a note and becomes available | The subclass must call this when it finishes playing a note and becomes available | ||||
| @@ -175,12 +175,12 @@ protected: | |||||
| */ | */ | ||||
| void clearCurrentNote() noexcept; | void clearCurrentNote() noexcept; | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| double currentSampleRate; | double currentSampleRate; | ||||
| MPENote currentlyPlayingNote; | MPENote currentlyPlayingNote; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| friend class MPESynthesiser; | friend class MPESynthesiser; | ||||
| uint32 noteStartTime; | uint32 noteStartTime; | ||||
| @@ -144,7 +144,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectValuesConsistent (MPEValue value, | void expectValuesConsistent (MPEValue value, | ||||
| int expectedValueAs7BitInt, | int expectedValueAs7BitInt, | ||||
| int expectedValueAs14BitInt, | int expectedValueAs14BitInt, | ||||
| @@ -157,7 +157,7 @@ private: | |||||
| expectFloatWithinRelativeError (value.asUnsignedFloat(), expectedValueAsUnsignedFloat, 0.0001f); | expectFloatWithinRelativeError (value.asUnsignedFloat(), expectedValueAsUnsignedFloat, 0.0001f); | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void expectFloatWithinRelativeError (float actualValue, float expectedValue, float maxRelativeError) | void expectFloatWithinRelativeError (float actualValue, float expectedValue, float maxRelativeError) | ||||
| { | { | ||||
| const float maxAbsoluteError = jmax (1.0f, std::fabs (expectedValue)) * maxRelativeError; | const float maxAbsoluteError = jmax (1.0f, std::fabs (expectedValue)) * maxRelativeError; | ||||
| @@ -37,7 +37,7 @@ | |||||
| class JUCE_API MPEValue | class JUCE_API MPEValue | ||||
| { | { | ||||
| public: | public: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| /** Default constructor. Constructs an MPEValue corresponding | /** Default constructor. Constructs an MPEValue corresponding | ||||
| to the centre value. | to the centre value. | ||||
| */ | */ | ||||
| @@ -87,7 +87,7 @@ public: | |||||
| bool operator!= (const MPEValue& other) const noexcept; | bool operator!= (const MPEValue& other) const noexcept; | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| MPEValue (int normalisedValue); | MPEValue (int normalisedValue); | ||||
| int normalisedValue; | int normalisedValue; | ||||
| }; | }; | ||||
| @@ -144,7 +144,7 @@ bool MPEZone::truncateToFit (MPEZone other) noexcept | |||||
| return true; | return true; | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| bool MPEZone::operator== (const MPEZone& other) const noexcept | bool MPEZone::operator== (const MPEZone& other) const noexcept | ||||
| { | { | ||||
| return masterChannel == other.masterChannel | return masterChannel == other.masterChannel | ||||
| @@ -284,7 +284,7 @@ public: | |||||
| } | } | ||||
| private: | private: | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void testOverlapsWith (int masterChannelFirst, int numNoteChannelsFirst, | void testOverlapsWith (int masterChannelFirst, int numNoteChannelsFirst, | ||||
| int masterChannelSecond, int numNoteChannelsSecond, | int masterChannelSecond, int numNoteChannelsSecond, | ||||
| bool expectedRetVal) | bool expectedRetVal) | ||||
| @@ -296,7 +296,7 @@ private: | |||||
| expect (second.overlapsWith (first) == expectedRetVal); | expect (second.overlapsWith (first) == expectedRetVal); | ||||
| } | } | ||||
| //========================================================================== | |||||
| //============================================================================== | |||||
| void testTruncateToFit (int masterChannelFirst, int numNoteChannelsFirst, | void testTruncateToFit (int masterChannelFirst, int numNoteChannelsFirst, | ||||
| int masterChannelSecond, int numNoteChannelsSecond, | int masterChannelSecond, int numNoteChannelsSecond, | ||||
| bool expectedRetVal, | bool expectedRetVal, | ||||