void CodeFileList::addFiles (const juce::StringArray& filepaths) { for (int i = filepaths.size(); --i >= 0;) addDirectory (filepaths.strings.getUnchecked (i)); cleanUpFileList(); }
//============================================================================== void CodeTool::writeLinesToStream (juce::FileOutputStream* stream, juce::StringArray& lines, const juce::String& lineEnding) { jassert (stream != nullptr); stream->setPosition (0); if (stream->truncate().wasOk()) { const int size = lines.size(); for (int i = 0; i < size; ++i) { const juce::String& line = lines.getReference (i); stream->writeText (line + (line.endsWith (lineEnding) ? juce::String::empty : lineEnding), false, false); } } }
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_debug("carla_get_cached_plugin_count(%i:%s)", ptype, CB::PluginType2Str(ptype)); switch (ptype) { case CB::PLUGIN_INTERNAL: { uint32_t count = 0; carla_get_native_plugins_data(&count); return count; } case CB::PLUGIN_LV2: { Lv2WorldClass& lv2World(Lv2WorldClass::getInstance()); lv2World.initIfNeeded(pluginPath); return lv2World.getPluginCount(); } case CB::PLUGIN_AU: { #ifdef CARLA_OS_MAC static bool initiated = false; if (! initiated) { using namespace juce; initiated = true; AudioUnitPluginFormat auFormat; gCachedAuPluginResults = auFormat.searchPathsForPlugins(juce::FileSearchPath(), false); } return static_cast<uint>(gCachedAuPluginResults.size()); #else return 0; #endif } default: return 0; } }
const CarlaCachedPluginInfo* carla_get_cached_plugin_info(CB::PluginType ptype, uint index) { carla_debug("carla_get_cached_plugin_info(%i:%s, %i)", ptype, CB::PluginType2Str(ptype), index); static CarlaCachedPluginInfo info; switch (ptype) { case CB::PLUGIN_INTERNAL: { uint32_t count = 0; const NativePluginDescriptor* const descs(carla_get_native_plugins_data(&count)); CARLA_SAFE_ASSERT_BREAK(index < count); CARLA_SAFE_ASSERT_BREAK(descs != nullptr); const NativePluginDescriptor& desc(descs[index]); info.category = static_cast<CB::PluginCategory>(desc.category); info.hints = 0x0; if (desc.hints & NATIVE_PLUGIN_IS_RTSAFE) info.hints |= CB::PLUGIN_IS_RTSAFE; if (desc.hints & NATIVE_PLUGIN_IS_SYNTH) info.hints |= CB::PLUGIN_IS_SYNTH; if (desc.hints & NATIVE_PLUGIN_HAS_UI) info.hints |= CB::PLUGIN_HAS_CUSTOM_UI; if (desc.hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) info.hints |= CB::PLUGIN_NEEDS_FIXED_BUFFERS; if (desc.hints & NATIVE_PLUGIN_NEEDS_UI_MAIN_THREAD) info.hints |= CB::PLUGIN_NEEDS_UI_MAIN_THREAD; if (desc.hints & NATIVE_PLUGIN_USES_MULTI_PROGS) info.hints |= CB::PLUGIN_USES_MULTI_PROGS; info.audioIns = desc.audioIns; info.audioOuts = desc.audioOuts; info.midiIns = desc.midiIns; info.midiOuts = desc.midiOuts; info.parameterIns = desc.paramIns; info.parameterOuts = desc.paramOuts; info.name = desc.name; info.label = desc.label; info.maker = desc.maker; info.copyright = desc.copyright; return &info; } case CB::PLUGIN_LV2: { Lv2WorldClass& lv2World(Lv2WorldClass::getInstance()); const LilvPlugin* const cPlugin(lv2World.getPluginFromIndex(index)); CARLA_SAFE_ASSERT_BREAK(cPlugin != nullptr); Lilv::Plugin lilvPlugin(cPlugin); CARLA_SAFE_ASSERT_BREAK(lilvPlugin.get_uri().is_uri()); carla_stdout("Filling info for LV2 with URI '%s'", lilvPlugin.get_uri().as_uri()); // features info.hints = 0x0; if (lilvPlugin.get_uis().size() > 0 || lilvPlugin.get_modgui_resources_directory().as_uri() != nullptr) info.hints |= CB::PLUGIN_HAS_CUSTOM_UI; { Lilv::Nodes lilvFeatureNodes(lilvPlugin.get_supported_features()); LILV_FOREACH(nodes, it, lilvFeatureNodes) { Lilv::Node lilvFeatureNode(lilvFeatureNodes.get(it)); const char* const featureURI(lilvFeatureNode.as_uri()); CARLA_SAFE_ASSERT_CONTINUE(featureURI != nullptr); if (std::strcmp(featureURI, LV2_CORE__hardRTCapable) == 0) info.hints |= CB::PLUGIN_IS_RTSAFE; } lilv_nodes_free(const_cast<LilvNodes*>(lilvFeatureNodes.me)); } // category info.category = CB::PLUGIN_CATEGORY_NONE; { Lilv::Nodes typeNodes(lilvPlugin.get_value(lv2World.rdf_type)); if (typeNodes.size() > 0) { if (typeNodes.contains(lv2World.class_allpass)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_amplifier)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_analyzer)) info.category = CB::PLUGIN_CATEGORY_UTILITY; if (typeNodes.contains(lv2World.class_bandpass)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_chorus)) info.category = CB::PLUGIN_CATEGORY_MODULATOR; if (typeNodes.contains(lv2World.class_comb)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_compressor)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_constant)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_converter)) info.category = CB::PLUGIN_CATEGORY_UTILITY; if (typeNodes.contains(lv2World.class_delay)) info.category = CB::PLUGIN_CATEGORY_DELAY; if (typeNodes.contains(lv2World.class_distortion)) info.category = CB::PLUGIN_CATEGORY_DISTORTION; if (typeNodes.contains(lv2World.class_dynamics)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_eq)) info.category = CB::PLUGIN_CATEGORY_EQ; if (typeNodes.contains(lv2World.class_envelope)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_expander)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_filter)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_flanger)) info.category = CB::PLUGIN_CATEGORY_MODULATOR; if (typeNodes.contains(lv2World.class_function)) info.category = CB::PLUGIN_CATEGORY_UTILITY; if (typeNodes.contains(lv2World.class_gate)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_generator)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_highpass)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_limiter)) info.category = CB::PLUGIN_CATEGORY_DYNAMICS; if (typeNodes.contains(lv2World.class_lowpass)) info.category = CB::PLUGIN_CATEGORY_FILTER; if (typeNodes.contains(lv2World.class_mixer)) info.category = CB::PLUGIN_CATEGORY_UTILITY; if (typeNodes.contains(lv2World.class_modulator)) info.category = CB::PLUGIN_CATEGORY_MODULATOR; if (typeNodes.contains(lv2World.class_multiEQ)) info.category = CB::PLUGIN_CATEGORY_EQ; if (typeNodes.contains(lv2World.class_oscillator)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_paraEQ)) info.category = CB::PLUGIN_CATEGORY_EQ; if (typeNodes.contains(lv2World.class_phaser)) info.category = CB::PLUGIN_CATEGORY_MODULATOR; if (typeNodes.contains(lv2World.class_pitch)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_reverb)) info.category = CB::PLUGIN_CATEGORY_DELAY; if (typeNodes.contains(lv2World.class_simulator)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_spatial)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_spectral)) info.category = CB::PLUGIN_CATEGORY_OTHER; if (typeNodes.contains(lv2World.class_utility)) info.category = CB::PLUGIN_CATEGORY_UTILITY; if (typeNodes.contains(lv2World.class_waveshaper)) info.category = CB::PLUGIN_CATEGORY_DISTORTION; if (typeNodes.contains(lv2World.class_instrument)) { info.category = CB::PLUGIN_CATEGORY_SYNTH; info.hints |= CB::PLUGIN_IS_SYNTH; } } lilv_nodes_free(const_cast<LilvNodes*>(typeNodes.me)); } // number data info.audioIns = 0; info.audioOuts = 0; info.midiIns = 0; info.midiOuts = 0; info.parameterIns = 0; info.parameterOuts = 0; for (uint i=0, count=lilvPlugin.get_num_ports(); i<count; ++i) { Lilv::Port lilvPort(lilvPlugin.get_port_by_index(i)); bool isInput; /**/ if (lilvPort.is_a(lv2World.port_input)) isInput = true; else if (lilvPort.is_a(lv2World.port_output)) isInput = false; else continue; /**/ if (lilvPort.is_a(lv2World.port_control)) { // skip some control ports if (lilvPort.has_property(lv2World.reportsLatency)) continue; if (LilvNode* const designationNode = lilv_port_get(lilvPort.parent, lilvPort.me, lv2World.designation.me)) { bool skip = false; if (const char* const designation = lilv_node_as_string(designationNode)) { /**/ if (std::strcmp(designation, LV2_CORE__control) == 0) skip = true; else if (std::strcmp(designation, LV2_CORE__freeWheeling) == 0) skip = true; else if (std::strcmp(designation, LV2_CORE__latency) == 0) skip = true; else if (std::strcmp(designation, LV2_PARAMETERS__sampleRate) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__bar) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__barBeat) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__beat) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__beatUnit) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__beatsPerBar) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__beatsPerMinute) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__frame) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__framesPerSecond) == 0) skip = true; else if (std::strcmp(designation, LV2_TIME__speed) == 0) skip = true; else if (std::strcmp(designation, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0) skip = true; } lilv_node_free(designationNode); if (skip) continue; } if (isInput) ++(info.parameterIns); else ++(info.parameterOuts); } else if (lilvPort.is_a(lv2World.port_audio)) { if (isInput) ++(info.audioIns); else ++(info.audioOuts); } else if (lilvPort.is_a(lv2World.port_cv)) { } else if (lilvPort.is_a(lv2World.port_atom)) { Lilv::Nodes supportNodes(lilvPort.get_value(lv2World.atom_supports)); for (LilvIter *it = lilv_nodes_begin(supportNodes.me); ! lilv_nodes_is_end(supportNodes.me, it); it = lilv_nodes_next(supportNodes.me, it)) { const Lilv::Node node(lilv_nodes_get(supportNodes.me, it)); CARLA_SAFE_ASSERT_CONTINUE(node.is_uri()); if (node.equals(lv2World.midi_event)) { if (isInput) ++(info.midiIns); else ++(info.midiOuts); } } lilv_nodes_free(const_cast<LilvNodes*>(supportNodes.me)); } else if (lilvPort.is_a(lv2World.port_event)) { if (lilvPort.supports_event(lv2World.midi_event)) { if (isInput) ++(info.midiIns); else ++(info.midiOuts); } } else if (lilvPort.is_a(lv2World.port_midi)) { if (isInput) ++(info.midiIns); else ++(info.midiOuts); } } // text data static CarlaString suri, sname, smaker, slicense; suri.clear(); sname.clear(); smaker.clear(); slicense.clear(); suri = lilvPlugin.get_uri().as_uri(); if (LilvNode* const nameNode = lilv_plugin_get_name(lilvPlugin.me)) { if (const char* const name = lilv_node_as_string(nameNode)) sname = name; lilv_node_free(nameNode); } if (const char* const author = lilvPlugin.get_author_name().as_string()) smaker = author; Lilv::Nodes licenseNodes(lilvPlugin.get_value(lv2World.doap_license)); if (licenseNodes.size() > 0) { if (const char* const license = licenseNodes.get_first().as_string()) slicense = license; } lilv_nodes_free(const_cast<LilvNodes*>(licenseNodes.me)); info.name = sname; info.label = suri; info.maker = smaker; info.copyright = slicense; return &info; } case CB::PLUGIN_AU: { #ifdef CARLA_OS_MAC const int indexi(static_cast<int>(index)); CARLA_SAFE_ASSERT_BREAK(indexi < gCachedAuPluginResults.size()); using namespace juce; String pluginId(gCachedAuPluginResults[indexi]); OwnedArray<PluginDescription> results; AudioUnitPluginFormat auFormat; auFormat.findAllTypesForFile(results, pluginId); CARLA_SAFE_ASSERT_BREAK(results.size() > 0); CARLA_SAFE_ASSERT(results.size() == 1); PluginDescription* const desc(results[0]); CARLA_SAFE_ASSERT_BREAK(desc != nullptr); info.category = CB::getPluginCategoryFromName(desc->category.toRawUTF8()); info.hints = 0x0; if (desc->isInstrument) info.hints |= CB::PLUGIN_IS_SYNTH; if (true) info.hints |= CB::PLUGIN_HAS_CUSTOM_UI; info.audioIns = static_cast<uint32_t>(desc->numInputChannels); info.audioOuts = static_cast<uint32_t>(desc->numOutputChannels); info.midiIns = desc->isInstrument ? 1 : 0; info.midiOuts = 0; info.parameterIns = 0; info.parameterOuts = 0; static CarlaString sname, slabel, smaker; sname = desc->name.toRawUTF8(); slabel = desc->fileOrIdentifier.toRawUTF8(); smaker = desc->manufacturerName.toRawUTF8(); info.name = sname; info.label = slabel; info.maker = smaker; info.copyright = gNullCharPtr; return &info; #else break; #endif } default: break; }