sintonia/library/ecasound-2.7.2/libecasound/eca-static-object-maps.cpp

635 lines
22 KiB
C++

// ------------------------------------------------------------------------
// eca-static-object-maps.h: Static object map instances
// Copyright (C) 2000-2004,2006,2008,2009 Kai Vehmanen
//
// Attributes:
// eca-style-version: 3 (see Ecasound Programmer's Guide)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// ------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
#include <dlfcn.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <kvu_numtostr.h>
#include <kvu_utils.h>
#include "eca-version.h"
#include "eca-chainop.h"
#include "audiofx.h"
#include "audiofx_misc.h"
#include "audiofx_amplitude.h"
#include "audiofx_analysis.h"
#include "audiofx_envelope_modulation.h"
#include "audiofx_filter.h"
#include "audiofx_rcfilter.h"
#include "audiofx_reverb.h"
#include "audiofx_mixing.h"
#include "audiofx_timebased.h"
#include "audiogate.h"
#include "audiofx_ladspa.h"
#include "generic-controller.h"
#include "ctrl-source.h"
#include "midi-cc.h"
#include "osc-gen.h"
#include "osc-gen-file.h"
#include "osc-sine.h"
#include "linear-envelope.h"
#include "two-stage-linear-envelope.h"
#include "stamp-ctrl.h"
#include "generic-linear-envelope.h"
#include "audioio-plugin.h"
#include "audioio-cdr.h"
#include "audioio-wave.h"
#ifdef ECA_COMPILE_OSS
#include "audioio-oss.h"
#endif
#include "audioio-ewf.h"
#include "audioio-mp3.h"
#include "audioio-ogg.h"
#include "audioio-mikmod.h"
#include "audioio-timidity.h"
#include "audioio-flac.h"
#include "audioio-aac.h"
#include "audioio-raw.h"
#include "audioio-null.h"
#include "audioio-rtnull.h"
#include "audioio-typeselect.h"
#include "audioio-resample.h"
#include "audioio-reverse.h"
#include "audioio-tone.h"
#include "audioio-acseq.h"
#ifndef ECA_ENABLE_AUDIOIO_PLUGINS
#ifdef ECA_COMPILE_AUDIOFILE
#include "plugins/audioio_af.h"
#endif
#ifdef ECA_COMPILE_SNDFILE
#include "plugins/audioio_sndfile.h"
#endif
#ifdef ECA_COMPILE_ALSA
#include "plugins/audioio_alsa.h"
#include "plugins/audioio_alsa_named.h"
#endif
#ifdef ECA_COMPILE_ARTS
#include "plugins/audioio_arts.h"
#endif
#ifdef ECA_COMPILE_JACK
#include "plugins/audioio_jack.h"
#endif
#endif /* ECA_ENABLE_AUDIOIO_PLUGINS */
#include "midiio-raw.h"
#ifdef ECA_COMPILE_ALSA
#include "midiio-aseq.h"
#endif
#include "eca-object-map.h"
#include "eca-preset-map.h"
#include "eca-static-object-maps.h"
#include "eca-resources.h"
#include "eca-logger.h"
#include "eca-error.h"
using std::cerr;
using std::endl;
using std::find;
using std::string;
using std::list;
using std::vector;
/**
* Declarations for static private helper functions
*/
static vector<EFFECT_LADSPA*> eca_create_ladspa_plugins(const string& fname);
static void eca_import_ladspa_plugins(ECA_OBJECT_MAP* objmap, bool reg_with_id);
#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
static void eca_import_internal_audioio_plugin(ECA_OBJECT_MAP* objmap, const string& filename);
#endif
/**
* Definitions of static member functions
*/
void ECA_STATIC_OBJECT_MAPS::register_audio_io_rt_objects(ECA_OBJECT_MAP* objmap)
{
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_audio_io_rt_objects()");
AUDIO_IO* device = 0;
#ifdef ECA_COMPILE_OSS
device = new OSSDEVICE();
objmap->register_object("/dev/dsp", "/dev/dsp[0-9]*", device);
objmap->register_object("/dev/sound/dsp", "/dev/sound/dsp[0-9]*", device);
#endif
device = new REALTIME_NULL();
objmap->register_object("rtnull", "^rtnull$", device);
#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
eca_import_internal_audioio_plugin(objmap, "libaudioio_alsa.so");
eca_import_internal_audioio_plugin(objmap, "libaudioio_alsa_named.so");
eca_import_internal_audioio_plugin(objmap, "libaudioio_arts.so");
eca_import_internal_audioio_plugin(objmap, "libaudioio_jack.so");
#else /* ECA_ENABLE_AUDIOIO_PLUGINS */
#ifdef ECA_COMPILE_ALSA
device = new AUDIO_IO_ALSA_PCM();
objmap->register_object("alsahw_09", "(^alsahw_09$)|(^alsaplugin_09$)", device);
device = new AUDIO_IO_ALSA_PCM_NAMED();
objmap->register_object("alsa_09", "^alsa_09$", device);
#endif
#ifdef ECA_COMPILE_ARTS
device = new ARTS_INTERFACE();
objmap->register_object("arts", "^arts$", device);
#endif
#ifdef ECA_COMPILE_JACK
device = new AUDIO_IO_JACK();
objmap->register_object("jack", "(^jack$)|(^jack_multi$)|(^jack_alsa$)|(^jack_auto$)|(^jack_generic$)", device);
#endif
#endif /* ECA_ENABLE_AUDIOIO_PLUGINS */
const ECA_OBJECT* aobj = 0;
aobj = objmap->object("alsahw_09");
if (aobj != 0) {
objmap->register_object("alsahw", "^alsahw$", const_cast<ECA_OBJECT*>(aobj));
objmap->register_object("alsaplugin", "^alsaplugin$", const_cast<ECA_OBJECT*>(aobj));
}
aobj = objmap->object("alsa_09");
if (aobj != 0) {
objmap->register_object("alsa", "^alsa$", const_cast<ECA_OBJECT*>(aobj));
}
}
void ECA_STATIC_OBJECT_MAPS::register_audio_io_nonrt_objects(ECA_OBJECT_MAP* objmap)
{
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_audio_io_nonrt_objects()");
bool native_flac = false;
objmap->register_object("wav", "wav$", new WAVEFILE());
objmap->register_object("ewf", "ewf$", new EWFFILE());
objmap->register_object("cdr", "cdr$", new CDRFILE());
AUDIO_IO* raw = new RAWFILE();
objmap->register_object("raw", "raw$", raw);
AUDIO_IO* mp3 = new MP3FILE();
objmap->register_object("mp3", "mp3$", mp3);
objmap->register_object("mp2", "mp2$", mp3);
AUDIO_IO* ogg = new OGG_VORBIS_INTERFACE();
objmap->register_object("ogg", "ogg$", ogg);
AUDIO_IO* mikmod = new MIKMOD_INTERFACE();
objmap->register_object("mikmod",
"(^mikmod$)|(xm$)|(669$)|(amf$)|(dsm$)|(far$)|(gdm$)|(imf$)|"
"(it$)|(m15$)|(ed$)|(mod$)|(mtm$)|(s3m$)|"
"(stm$)|(stx$)|(ult$)|(uni$)", mikmod);
AUDIO_IO* timidity = new TIMIDITY_INTERFACE();
objmap->register_object("mid", "(mid$)|(midi$)", timidity);
AUDIO_IO* forkedaac = new AAC_FORKED_INTERFACE();
objmap->register_object("aac", "aac$", forkedaac);
objmap->register_object("mp4", "mp4$", forkedaac);
objmap->register_object("m4a", "m4a$", forkedaac);
#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
eca_import_internal_audioio_plugin(objmap, "libaudioio_af.so");
eca_import_internal_audioio_plugin(objmap, "libaudioio_sndfile.so");
#else /* !ECA_ENABLE_AUDIOIO_PLUGINS */
/* ---------------------------------------------------------*/
/* register file types to plugins handling audio file types */
#if defined(ECA_COMPILE_SNDFILE) || defined(ECA_COMPILE_AUDIOFILE)
string common_types ("(aif*$)|(au$)|(snd$)");
#endif
#ifdef ECA_COMPILE_SNDFILE
SNDFILE_INTERFACE* sndfile = new SNDFILE_INTERFACE();
/* 1. register types supported by libsndfile */
string sf_types ("(^sndfile$)");
list<string> el = sndfile->supported_extensions();
list<string>::const_iterator i = el.begin();
string sf_all_types;
while(i != el.end()) {
sf_all_types += *i + ",";
++i;
}
ECA_LOG_MSG(ECA_LOGGER::user_objects,
"All libsndfile supported extensions: " + sf_all_types);
if (find(el.begin(), el.end(), "flac") != el.end()) {
sf_types += "|(flac$)";
native_flac = true;
}
if (find(el.begin(), el.end(), "avr") != el.end()) sf_types += "|(avr$)";
if (find(el.begin(), el.end(), "caf") != el.end()) sf_types += "|(caf$)";
if (find(el.begin(), el.end(), "htk") != el.end()) sf_types += "|(htk$)";
if (find(el.begin(), el.end(), "iff") != el.end()) sf_types += "|(iff$)";
if (find(el.begin(), el.end(), "mat") != el.end()) sf_types += "|(mat$)";
if (find(el.begin(), el.end(), "paf") != el.end()) sf_types += "|(paf$)";
if (find(el.begin(), el.end(), "pvf") != el.end()) sf_types += "|(pvf$)";
if (find(el.begin(), el.end(), "nist") != el.end()) sf_types += "|(nist$)";
if (find(el.begin(), el.end(), "sf") != el.end()) sf_types += "|(sf$)";
if (find(el.begin(), el.end(), "sd2") != el.end()) sf_types += "|(sd2$)";
if (find(el.begin(), el.end(), "sds") != el.end()) sf_types += "|(sds$)";
if (find(el.begin(), el.end(), "voc") != el.end()) sf_types += "|(voc$)";
if (find(el.begin(), el.end(), "w64") != el.end()) sf_types += "|(w64$)";
if (find(el.begin(), el.end(), "xi") != el.end()) sf_types += "|(xi$)";
/* add formats supported by both libaudiofile and libsndfile */
sf_types += string("|") + common_types;
common_types.clear();
objmap->register_object("sndfile", sf_types.c_str(), dynamic_cast<AUDIO_IO*>(sndfile));
#endif
#ifdef ECA_COMPILE_AUDIOFILE
/* 2. register types for libaudiofile */
string af_types ("(^audiofile$)");
/* note, if sndfile not available, common_types are registered
* to libaudiofile */
if (common_types.size() > 0)
af_types += string("|") + common_types;
AUDIO_IO* af = new AUDIOFILE_INTERFACE();
objmap->register_object("audiofile", af_types.c_str(), af);
#endif
/* ---------------------------------------------------------*/
#endif /* ECA_ENABLE_AUDIOIO_PLUGINS */
objmap->register_object("-", "^-$", raw);
objmap->register_object("stdin", "^stdin$", raw);
objmap->register_object("stdout", "^stdout$", raw);
objmap->register_object("null", "^null$", new NULLFILE());
objmap->register_object("typeselect", "^typeselect$", new AUDIO_IO_TYPESELECT());
objmap->register_object("resample", "^resample$", new AUDIO_IO_RESAMPLE());
objmap->register_object("resample-hq", "^resample-hq$", new AUDIO_IO_RESAMPLE());
objmap->register_object("resample-lq", "^resample-lq$", new AUDIO_IO_RESAMPLE());
objmap->register_object("reverse", "^reverse$", new AUDIO_IO_REVERSE());
objmap->register_object("tone", "^tone$", new AUDIO_IO_TONE());
objmap->register_object("audioloop", "^(audioloop|select|playat)$", new AUDIO_CLIP_SEQUENCER());
if (native_flac != true) {
AUDIO_IO* forkedflac = new FLAC_FORKED_INTERFACE();
objmap->register_object("flac", "flac$", forkedflac);
}
}
void ECA_STATIC_OBJECT_MAPS::register_chain_operator_objects(ECA_OBJECT_MAP* objmap)
{
#ifndef ECA_DISABLE_EFFECTS
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_chain_operator_objects()");
objmap->register_object("eS", "^eS$", new EFFECT_AUDIO_STAMP());
objmap->register_object("ea", "^ea$", new EFFECT_AMPLIFY());
objmap->register_object("eadb", "^eadb$", new EFFECT_AMPLIFY_DB());
objmap->register_object("eac", "^eac$", new EFFECT_AMPLIFY_CHANNEL());
objmap->register_object("eal", "^eal$", new EFFECT_LIMITER());
objmap->register_object("eaw", "^eaw$", new EFFECT_AMPLIFY_CLIPCOUNT());
objmap->register_object("ec", "^ec$", new EFFECT_COMPRESS());
objmap->register_object("eca", "^eca$", new ADVANCED_COMPRESSOR());
objmap->register_object("eemb", "^eemb$", new EFFECT_PULSE_GATE_BPM());
objmap->register_object("eemp", "^eemp$", new EFFECT_PULSE_GATE());
objmap->register_object("eemt", "^eemt$", new EFFECT_TREMOLO());
objmap->register_object("ef1", "^ef1$", new EFFECT_RESONANT_BANDPASS());
objmap->register_object("ef3", "^ef3$", new EFFECT_RESONANT_LOWPASS());
objmap->register_object("ef4", "^ef4$", new EFFECT_RC_LOWPASS_FILTER());
objmap->register_object("efa", "^efa$", new EFFECT_ALLPASS_FILTER());
objmap->register_object("efb", "^efb$", new EFFECT_BANDPASS());
objmap->register_object("efc", "^efc$", new EFFECT_COMB_FILTER());
objmap->register_object("efh", "^efh$", new EFFECT_HIGHPASS());
objmap->register_object("efi", "^efi$", new EFFECT_INVERSE_COMB_FILTER());
objmap->register_object("efl", "^efl$", new EFFECT_LOWPASS());
objmap->register_object("efr", "^efr$", new EFFECT_BANDREJECT());
objmap->register_object("efs", "^efs$", new EFFECT_RESONATOR());
objmap->register_object("ei", "^ei$", new EFFECT_PITCH_SHIFT());
objmap->register_object("enm", "^enm$", new EFFECT_NOISEGATE());
objmap->register_object("epp", "^epp$", new EFFECT_NORMAL_PAN());
objmap->register_object("chorder", "^chorder$", new EFFECT_CHANNEL_ORDER());
EFFECT_CHANNEL_COPY *op_cp = new EFFECT_CHANNEL_COPY();
objmap->register_object("chcopy", "^chcopy$", op_cp);
objmap->register_object("erc", "^erc$", op_cp);
objmap->register_object("chmove", "^chmove$", new EFFECT_CHANNEL_MOVE());
objmap->register_object("chmute", "^chmute$", new EFFECT_CHANNEL_MUTE());
EFFECT_MIX_TO_CHANNEL *op_mix = new EFFECT_MIX_TO_CHANNEL();
objmap->register_object("erm", "^erm$", op_mix);
objmap->register_object("chmix", "^chmix$", op_mix);
objmap->register_object("etc", "^etc$", new EFFECT_CHORUS());
objmap->register_object("etd", "^etd$", new EFFECT_DELAY());
objmap->register_object("ete", "^ete$", new ADVANCED_REVERB());
objmap->register_object("etf", "^etf$", new EFFECT_FAKE_STEREO());
objmap->register_object("etl", "^etl$", new EFFECT_FLANGER());
objmap->register_object("etm", "^etm$", new EFFECT_MULTITAP_DELAY());
objmap->register_object("etp", "^etp$", new EFFECT_PHASER());
objmap->register_object("etr", "^etr$", new EFFECT_REVERB());
objmap->register_object("ev", "^ev$", new EFFECT_VOLUME_BUCKETS());
objmap->register_object("evp", "^evp$", new EFFECT_VOLUME_PEAK());
objmap->register_object("ezf", "^ezf$", new EFFECT_DCFIND());
objmap->register_object("ezx", "^ezx$", new EFFECT_DCFIX());
objmap->register_object("gc", "^gc$", new TIME_CROP_GATE());
objmap->register_object("ge", "^ge$", new THRESHOLD_GATE());
objmap->register_object("gm", "^gm$", new MANUAL_GATE());
#endif
}
void ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_objects(ECA_OBJECT_MAP* objmap)
{
#ifndef ECA_DISABLE_EFFECTS
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_ladspa_plugin_objects()");
eca_import_ladspa_plugins(objmap, false);
#endif
}
void ECA_STATIC_OBJECT_MAPS::register_ladspa_plugin_id_objects(ECA_OBJECT_MAP* objmap)
{
#ifndef ECA_DISABLE_EFFECTS
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_ladspa_plugin_id_objects()");
eca_import_ladspa_plugins(objmap, true);
#endif
}
void ECA_STATIC_OBJECT_MAPS::register_preset_objects(ECA_PRESET_MAP* objmap)
{
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_preset_objects()");
/* @see ECA_PRESET_MAP */
}
void ECA_STATIC_OBJECT_MAPS::register_controller_objects(ECA_OBJECT_MAP* objmap)
{
#ifndef ECA_DISABLE_EFFECTS
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_controller_objects()");
objmap->register_object("kf", "^kf$", new GENERIC_CONTROLLER(new GENERIC_OSCILLATOR_FILE()));
objmap->register_object("kog", "^kog$", new GENERIC_CONTROLLER(new GENERIC_OSCILLATOR()));
objmap->register_object("kl", "^kl$", new GENERIC_CONTROLLER(new LINEAR_ENVELOPE()));
objmap->register_object("kl2", "^kl2$", new GENERIC_CONTROLLER(new TWO_STAGE_LINEAR_ENVELOPE()));
objmap->register_object("klg", "^klg$", new GENERIC_CONTROLLER(new GENERIC_LINEAR_ENVELOPE()));
objmap->register_object("km", "^km$", new GENERIC_CONTROLLER(new MIDI_CONTROLLER()));
objmap->register_object("kos", "^kos$", new GENERIC_CONTROLLER(new SINE_OSCILLATOR()));
objmap->register_object("ksv", "^ksv$", new GENERIC_CONTROLLER(new VOLUME_ANALYZE_CONTROLLER()));
#endif
}
void ECA_STATIC_OBJECT_MAPS::register_midi_device_objects(ECA_OBJECT_MAP* objmap)
{
ECA_LOG_MSG(ECA_LOGGER::system_objects, "register_midi_device_objects()");
objmap->register_object("rawmidi", "^rawmidi$", new MIDI_IO_RAW());
#ifdef ECA_COMPILE_ALSA
objmap->register_object("alsaseq", "^alsaseq$", new MIDI_IO_ASEQ());
#endif
}
/**
* Definitions for static private helper functions
*/
#ifdef ECA_ENABLE_AUDIOIO_PLUGINS
/**
* Load ecasound's internal plugins. Not used since 2.2.0.
*/
static void eca_import_internal_audioio_plugin(ECA_OBJECT_MAP* objmap,
const string& filename)
{
ECA_RESOURCES ecarc;
string libdir = ecarc.resource("internal-plugin-directory");
struct stat fbuf;
if (stat(libdir.c_str(), &fbuf) < 0) {
ECA_LOG_MSG(ECA_LOGGER::info, "Internal-plugin directory not found. Check your ~/.ecasoundrc!");
return;
}
string file = libdir + string("/") + filename;
audio_io_descriptor desc_func = 0;
audio_io_interface_version plugin_version = 0;
audio_io_keyword plugin_keyword = 0;
audio_io_keyword_regex plugin_keyword_regex = 0;
void *plugin_handle = dlopen(file.c_str(), RTLD_NOW | RTLD_GLOBAL); /* RTLD_LAZY */
if (plugin_handle != 0) {
plugin_version = (audio_io_interface_version)dlsym(plugin_handle, "audio_io_interface_version");
if (plugin_version != 0) {
int version = plugin_version();
if (version < ecasound_library_version_current -
ecasound_library_version_age ||
version > ecasound_library_version_current) {
ECA_LOG_MSG(ECA_LOGGER::info,
"Opening internal plugin file \"" +
file +
"\" failed. Plugin version " +
kvu_numtostr(version) +
" doesn't match libecasound version " +
kvu_numtostr(ecasound_library_version_current) + "." +
kvu_numtostr(ecasound_library_version_revision) + "." +
kvu_numtostr(ecasound_library_version_age) + ".");
}
else {
desc_func = (audio_io_descriptor)dlsym(plugin_handle, "audio_io_descriptor");
plugin_keyword = (audio_io_keyword)dlsym(plugin_handle, "audio_io_keyword");
plugin_keyword_regex = (audio_io_keyword_regex)dlsym(plugin_handle, "audio_io_keyword_regex");
if (desc_func != 0) {
AUDIO_IO* aobj = desc_func();
if (plugin_keyword != 0 && plugin_keyword_regex != 0) {
objmap->register_object(plugin_keyword(), plugin_keyword_regex(), aobj);
// std::cerr << "Registering audio io type: " << aobj->name() << "\nType keyword " << plugin_keyword() << ", regex " << plugin_keyword_regex() << "." << std::endl;
}
}
}
}
else {
std::cerr << "(eca-static-object-maps) dlsym() failed; " << file;
std::cerr << ": \"" << dlerror() << "\"." << std::endl;
}
}
else {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
"dlopen() failed; " + file +
+ ": \"" + string(dlerror()) + "\".");
}
if (plugin_handle == 0 ||
plugin_version == 0 ||
plugin_keyword == 0 ||
plugin_keyword_regex == 0 ||
desc_func == 0) {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
"Opening internal plugin file \"" +
file + "\" failed.");
}
}
#endif
static void eca_import_ladspa_plugins(ECA_OBJECT_MAP* objmap, bool reg_with_id)
{
DIR *dp;
vector<string> dir_names;
char* env = std::getenv("LADSPA_PATH");
if (env != 0) {
dir_names = kvu_string_to_vector(string(env), ':');
}
/* add directories mentioned in 'ladspa-plugin-directory'
* to the directory search list and remove duplicates */
ECA_RESOURCES ecarc;
string add_file = ecarc.resource("ladspa-plugin-directory");
vector<string> more_dir_names = kvu_string_to_vector(add_file, ':');
vector<string>::const_iterator di = more_dir_names.begin();
while(di != more_dir_names.end()) {
if (find(dir_names.begin(), dir_names.end(), *di) == dir_names.end()) {
dir_names.push_back(*di);
}
++di;
}
/* go through all directories in the list and
* try to open all encountered files as LADSPA plugins */
struct stat statbuf;
vector<string>::const_iterator p = dir_names.begin();
while (p != dir_names.end()) {
dp = opendir(p->c_str());
if (dp != 0) {
struct dirent *entry = readdir(dp);
for(; entry != 0; entry = readdir(dp)) {
string full_path_str = string(*p + "/" + entry->d_name);
int err = lstat(full_path_str.c_str(), &statbuf);
if (err) {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
string("Invalid LADSPA plugin file \"") +
entry->d_name + "\" (" +
strerror(errno) + ").");
continue;
}
if (S_ISDIR(statbuf.st_mode)) {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
string("Skipping directory \"") +
entry->d_name + "\" while loading LADSPA plugins.");
continue;
}
if (S_ISCHR(statbuf.st_mode) ||
S_ISBLK(statbuf.st_mode)) {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
string("Skipping device \"") +
entry->d_name + "\" while loading LADSPA plugins.");
continue;
}
if (S_ISFIFO(statbuf.st_mode) ||
S_ISSOCK(statbuf.st_mode)) {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
string("Skipping pipe/socket \"") +
entry->d_name + "\" while loading LADSPA plugins.");
continue;
}
vector<EFFECT_LADSPA*> ladspa_plugins;
try {
if (entry->d_name[0] != '.')
ladspa_plugins = eca_create_ladspa_plugins(full_path_str.c_str());
}
catch(ECA_ERROR& e) { }
for(unsigned int n = 0; n < ladspa_plugins.size(); n++) {
if (reg_with_id == true) {
objmap->register_object(kvu_numtostr(ladspa_plugins[n]->unique_number()),
"^" + kvu_numtostr(ladspa_plugins[n]->unique_number()) + "$",
ladspa_plugins[n]);
}
else {
objmap->register_object(ladspa_plugins[n]->unique(), "^" +
kvu_string_regex_meta_escape(ladspa_plugins[n]->unique()) + "$",
ladspa_plugins[n]);
}
}
}
}
++p;
}
}
static vector<EFFECT_LADSPA*> eca_create_ladspa_plugins(const string& fname)
{
vector<EFFECT_LADSPA*> plugins;
#ifndef ECA_DISABLE_EFFECTS
void *plugin_handle = dlopen(fname.c_str(), RTLD_NOW);
if (plugin_handle != 0) {
LADSPA_Descriptor_Function desc_func;
desc_func = (LADSPA_Descriptor_Function)dlsym(plugin_handle, "ladspa_descriptor");
if (desc_func != 0) {
const LADSPA_Descriptor *plugin_desc = 0;
for (int i = 0;; i++) {
plugin_desc = desc_func(i);
if (plugin_desc == 0) break;
try {
plugins.push_back(new EFFECT_LADSPA(plugin_desc));
}
catch (ECA_ERROR&) { }
plugin_desc = 0;
}
}
else {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
"Unable find plugin LADSPA-descriptor.");
}
}
else {
ECA_LOG_MSG(ECA_LOGGER::user_objects,
string("Unable to open plugin file \"") + fname + "\".");
}
#endif
return plugins;
}