Logo Search packages:      
Sourcecode: naspro-bridges-bad version File versions  Download package

pluglib.c

/*
 * NASPRO - NASPRO Architecture for Sound Processing
 * DSSI bridge
 *
 * Copyright (C) 2007-2010 Stefano D'Angelo <zanga.mail@gmail.com>
 *
 * See the COPYING file for license conditions.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <dssi.h>

#include <NASPRO/core/lib.h>

#include "pluglib.h"
#include "descriptor.h"

nacore_avl_tree_t _nadssi_pluglib_desc_tree = NULL;

struct pluglib
  {
      nacore_dl_module_t             dl_module;
      struct nacore_descriptor      *descs;
      size_t                         descs_count;
      struct nacore_port_descriptor *port_descs;
      size_t                         port_descs_count;
      char                    *uris;
      size_t                         uris_size;
  };

static struct pluglib *pluglibs = NULL;
static size_t pluglibs_count = 0;

static void
pluglib_load(const char *file, const char *basename, void *data)
{
      nacore_dl_module_t dl_module;
      const DSSI_Descriptor *ddesc;
      DSSI_Descriptor_Function get_desc;
      struct pluglib *tmp_pluglibs;
      struct nacore_descriptor *tmp_descs;
      struct nacore_port_descriptor *tmp_port_descs;
      char *tmp_uris;
      size_t descs_count, ports_count, uris_size;
      unsigned long i;
      char *c;

      dl_module = nacore_dl_open(file);
      if (dl_module == NULL)
            goto dl_open_err;

      if (nacore_dl_sym(dl_module, "naspro_backbridge") != NULL)
            goto backbridge;

      *(void **)(&get_desc) = nacore_dl_sym(dl_module, "dssi_descriptor");
      if (get_desc == NULL)
            goto get_desc_err;

      for (i = 0, descs_count = 0, ports_count = 0, uris_size = 0;
           (ddesc = get_desc(i)) != NULL; i++)
        {
            if (ddesc->DSSI_API_Version != 1)
                  continue;

            ports_count += ddesc->LADSPA_Plugin->PortCount;
            if (ddesc->run_synth != NULL)
                  ports_count++;
            c = strrchr(basename, '.');
            uris_size += c - basename
                       + strlen(ddesc->LADSPA_Plugin->Label) + 11;
            descs_count++;
        }
      if (descs_count == 0)
            goto no_desc;

      tmp_descs = malloc(descs_count * sizeof(struct nacore_descriptor));
      if (tmp_descs == NULL)
            goto descs_err;

      tmp_port_descs = NULL;
      if (ports_count != 0)
        {
            tmp_port_descs = malloc(ports_count
                        * sizeof(struct nacore_port_descriptor));
            if (tmp_port_descs == NULL)
                  goto port_descs_err;
        }

      tmp_uris = malloc(uris_size);
      if (tmp_uris == NULL)
            goto uris_err;

      tmp_pluglibs = realloc(pluglibs,
                         (pluglibs_count + 1) * sizeof(struct pluglib));
      if (tmp_pluglibs == NULL)
            goto pluglibs_err;

      pluglibs = tmp_pluglibs;
      tmp_pluglibs = pluglibs + pluglibs_count;
      pluglibs_count++;

      tmp_pluglibs->dl_module = dl_module;

      tmp_pluglibs->descs = tmp_descs;
      tmp_pluglibs->descs_count = descs_count;
      tmp_pluglibs->port_descs = tmp_port_descs;
      tmp_pluglibs->port_descs_count = ports_count;
      tmp_pluglibs->uris = tmp_uris;
      tmp_pluglibs->uris_size = uris_size;

      for (i = 0, descs_count = 0, ports_count = 0, uris_size = 0;
           (ddesc = get_desc(i)) != NULL; i++)
        {
            if (ddesc->DSSI_API_Version != 1)
                  continue;

            tmp_pluglibs->descs[descs_count].port_descs =
                  tmp_pluglibs->port_descs + ports_count;
            tmp_pluglibs->descs[descs_count].port_descs_count =
                  ddesc->LADSPA_Plugin->PortCount;
            if (ddesc->run_synth != NULL)
                  tmp_pluglibs->descs[descs_count].port_descs_count++;
            tmp_pluglibs->descs[descs_count].uri =
                  tmp_pluglibs->uris + uris_size;
            c = strrchr(basename, '.');
            strcpy(tmp_pluglibs->descs[descs_count].uri, "urn:dssi:");
            strncat(tmp_pluglibs->descs[descs_count].uri, basename,
                  c - basename);
            strcat(tmp_pluglibs->descs[descs_count].uri, ":");
            strcat(tmp_pluglibs->descs[descs_count].uri,
                   ddesc->LADSPA_Plugin->Label);

            _nadssi_descriptor_fill(tmp_pluglibs->descs + descs_count,
                              ddesc);

            nacore_avl_tree_add(_nadssi_pluglib_desc_tree,
                            tmp_pluglibs->descs + descs_count);

            ports_count += ddesc->LADSPA_Plugin->PortCount;
            if (ddesc->run_synth != NULL)
                  ports_count++;
            uris_size += c - basename
                       + strlen(ddesc->LADSPA_Plugin->Label) + 11;
            descs_count++;
        }

      return;

pluglibs_err:
      free(tmp_uris);
uris_err:
      if (tmp_port_descs != NULL)
            free(tmp_port_descs);
port_descs_err:
      free(tmp_descs);
descs_err:
no_desc:
get_desc_err:
backbridge:
      nacore_dl_close(dl_module);
dl_open_err:
      return;
}

void
_nadssi_pluglib_load_all()
{
      char *dssi_path;
      char *ladspa_path;

      _nadssi_pluglib_desc_tree = nacore_avl_tree_new(
            nacore_content_cmp_descriptor_by_uri,
            nacore_key_cmp_descriptor_by_uri);
      if (_nadssi_pluglib_desc_tree == NULL)
            return;

      dssi_path = nacore_env_get_var("DSSI_PATH");
      ladspa_path = nacore_env_get_var("LADSPA_PATH");
      if (NACORE_STRING_IS_NULL_OR_EMPTY(ladspa_path)
          && NACORE_STRING_IS_NULL_OR_EMPTY(dssi_path))
        {
#ifdef __APPLE__
            nacore_path_home_for_each("Library/Audio/Plug-Ins/DSSI:.dssi",
                                pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/Library/Audio/Plug-Ins/DSSI"
                             "/usr/local/lib/dssi:/usr/lib/dssi",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#elif defined (__HAIKU__)
            /* FIXME: find_directory() should be used */
            nacore_path_home_for_each("config/add-ons/dssi", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/boot/common/add-ons/dssi",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#elif defined (__SYLLABLE__)
            nacore_path_home_for_each("extensions/dssi", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/system/extensions/dssi", pluglib_load,
                             nacore_dl_filename_filter, NULL);
#else
            nacore_path_home_for_each(".dssi", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/usr/local/lib/dssi:/usr/lib/dssi",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#endif
        }
      else
        {
            if (!NACORE_STRING_IS_NULL_OR_EMPTY(dssi_path))
                  nacore_path_for_each(dssi_path, pluglib_load,
                                   nacore_dl_filename_filter, NULL);
            if (!NACORE_STRING_IS_NULL_OR_EMPTY(ladspa_path))
                  nacore_path_for_each(ladspa_path, pluglib_load,
                                   nacore_dl_filename_filter, NULL);
        }

      if (ladspa_path != NULL)
            nacore_env_free_var_value(ladspa_path);
      if (dssi_path != NULL)
            nacore_env_free_var_value(dssi_path);
}

void
_nadssi_pluglib_unload_all()
{
      size_t i;

      if (pluglibs == NULL)
            return;

      for (i = 0; i < pluglibs_count; i++)
        {
            nacore_dl_close(pluglibs[i].dl_module);
            free(pluglibs[i].descs);
            free(pluglibs[i].port_descs);
            free(pluglibs[i].uris);
        }

      free(pluglibs);
      pluglibs = NULL;
      pluglibs_count = 0;

      nacore_avl_tree_free(_nadssi_pluglib_desc_tree);
      _nadssi_pluglib_desc_tree = NULL;
}

Generated by  Doxygen 1.6.0   Back to index