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

pluglib.c

/*
 * NASPRO - NASPRO Architecture for Sound Processing
 * LADSPA 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 <ladspa.h>

#include <NASPRO/core/lib.h>

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

nacore_avl_tree_t _naladspa_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 nacore_avl_tree_t uid_tree;

static size_t
uint_to_dec_str_len(unsigned long i)
{
      size_t ret;

      ret = 0;
      do
        {
            i /= 10;
            ret++;
        }
      while (i != 0);

      return ret;
}

static void
pluglib_load(const char *file, const char *basename, void *data)
{
      nacore_dl_module_t dl_module;
      const LADSPA_Descriptor *ldesc;
      LADSPA_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;
      void *p;

      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, "ladspa_descriptor");
      if (get_desc == NULL)
            goto get_desc_err;

      for (i = 0, descs_count = 0, ports_count = 0, uris_size = 0;
           (ldesc = get_desc(i)) != NULL; i++)
        {
            p = nacore_avl_tree_find(uid_tree, (void *)&ldesc->UniqueID);
            if (p != NULL)
                  continue;

            nacore_avl_tree_add(uid_tree, (void *)ldesc);

            ports_count += ldesc->PortCount;
            uris_size += uint_to_dec_str_len(ldesc->UniqueID) + 12;
            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;
           (ldesc = get_desc(i)) != NULL; i++)
        {
            p = nacore_avl_tree_find(uid_tree, (void *)&ldesc->UniqueID);
            if (p != ldesc)
                  continue;

            tmp_pluglibs->descs[descs_count].port_descs =
                  tmp_pluglibs->port_descs + ports_count;
            tmp_pluglibs->descs[descs_count].port_descs_count =
                  ldesc->PortCount;
            tmp_pluglibs->descs[descs_count].uri =
                  tmp_pluglibs->uris + uris_size;
            sprintf(tmp_pluglibs->descs[descs_count].uri, "urn:ladspa:%lu",
                  ldesc->UniqueID);

            _naladspa_descriptor_fill(tmp_pluglibs->descs + descs_count,
                                ldesc);

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

            ports_count += ldesc->PortCount;
            uris_size += uint_to_dec_str_len(ldesc->UniqueID) + 12;
            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;
}

static int
uid_content_cmp(void *c1, void *c2)
{
      if (((LADSPA_Descriptor *)c1)->UniqueID
          < ((LADSPA_Descriptor *)c2)->UniqueID)
            return -1;
      if (((LADSPA_Descriptor *)c1)->UniqueID
          == ((LADSPA_Descriptor *)c2)->UniqueID)
            return 0;
      return 1;
}

static int
uid_key_cmp(void *content, void *key)
{
      if (((LADSPA_Descriptor *)content)->UniqueID < *((unsigned long *)key))
            return -1;
      if (((LADSPA_Descriptor *)content)->UniqueID == *((unsigned long *)key))
            return 0;
      return 1;
}

void
_naladspa_pluglib_load_all()
{
      char *ladspa_path;

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

      uid_tree = nacore_avl_tree_new(uid_content_cmp, uid_key_cmp);
      if (uid_tree == NULL)
        {
            nacore_avl_tree_free(_naladspa_pluglib_desc_tree);
            _naladspa_pluglib_desc_tree = NULL;
            return;
        }

      _naladspa_lrdf_load_all();

      ladspa_path = nacore_env_get_var("LADSPA_PATH");
      if (NACORE_STRING_IS_NULL_OR_EMPTY(ladspa_path))
        {
#ifdef __APPLE__
            nacore_path_home_for_each("Library/Audio/Plug-Ins/LADSPA"
                                ":.ladspa", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/Library/Audio/Plug-Ins/LADSPA"
                             ":/usr/local/lib/ladspa:/usr/lib/ladspa",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#elif defined (__HAIKU__)
            /* FIXME: find_directory() should be used */
            nacore_path_home_for_each(".ladspa", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/usr/local/lib/ladspa:/usr/lib/ladspa",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#elif defined (__SYLLABLE__)
            nacore_path_home_for_each("extensions/ladspa", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/system/extensions/ladspa",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#else
            nacore_path_home_for_each(".ladspa", pluglib_load,
                                nacore_dl_filename_filter, NULL);
            nacore_path_for_each("/usr/local/lib/ladspa:/usr/lib/ladspa",
                             pluglib_load, nacore_dl_filename_filter,
                             NULL);
#endif
        }
      else
            nacore_path_for_each(ladspa_path, pluglib_load,
                             nacore_dl_filename_filter, NULL);

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

      nacore_avl_tree_free(uid_tree);
}

void
_naladspa_pluglib_unload_all()
{
      size_t i, j;

      if (pluglibs == NULL)
            return;

      for (i = 0; i < pluglibs_count; i++)
        {
            for (j = 0; j < pluglibs[i].descs_count; j++)
                  _naladspa_descriptor_free_data(pluglibs[i].descs + j);

            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;

      _naladspa_lrdf_unload_all();

      nacore_avl_tree_free(_naladspa_pluglib_desc_tree);
      _naladspa_pluglib_desc_tree = NULL;
}

Generated by  Doxygen 1.6.0   Back to index