"Fossies" - the Fresh Open Source Software Archive

Member "audacious-plugins-3.10.1/src/ladspa/effect.cc" (26 Dec 2018, 6255 Bytes) of package /linux/misc/audacious-plugins-3.10.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "effect.cc" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * LADSPA Host for Audacious
    3  * Copyright 2011 John Lindgren
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright notice,
    9  *    this list of conditions, and the following disclaimer.
   10  *
   11  * 2. Redistributions in binary form must reproduce the above copyright notice,
   12  *    this list of conditions, and the following disclaimer in the documentation
   13  *    provided with the distribution.
   14  *
   15  * This software is provided "as is" and without any warranty, express or
   16  * implied. In no event shall the authors be liable for any damages arising from
   17  * the use of this software.
   18  */
   19 
   20 #include <assert.h>
   21 
   22 #include "ladspa.h"
   23 #include "plugin.h"
   24 
   25 #include <libaudcore/runtime.h>
   26 
   27 static int ladspa_channels, ladspa_rate;
   28 
   29 static void start_plugin (LoadedPlugin & loaded)
   30 {
   31     if (loaded.active)
   32         return;
   33 
   34     loaded.active = 1;
   35 
   36     PluginData & plugin = loaded.plugin;
   37     const LADSPA_Descriptor & desc = plugin.desc;
   38 
   39     int ports = plugin.in_ports.len ();
   40 
   41     if (ports == 0 || ports != plugin.out_ports.len ())
   42     {
   43         AUDERR ("Plugin has unusable port configuration: %s\n", desc.Name);
   44         return;
   45     }
   46 
   47     if (ladspa_channels % ports != 0)
   48     {
   49         AUDERR ("Plugin cannot be used with %d channels: %s\n",
   50          ladspa_channels, desc.Name);
   51         return;
   52     }
   53 
   54     int instances = ladspa_channels / ports;
   55 
   56     loaded.in_bufs.insert (0, ladspa_channels);
   57     loaded.out_bufs.insert (0, ladspa_channels);
   58 
   59     for (int i = 0; i < instances; i ++)
   60     {
   61         LADSPA_Handle handle = desc.instantiate (& desc, ladspa_rate);
   62         loaded.instances.append (handle);
   63 
   64         int controls = plugin.controls.len ();
   65         for (int c = 0; c < controls; c ++)
   66             desc.connect_port (handle, plugin.controls[c].port, & loaded.values[c]);
   67 
   68         for (int p = 0; p < ports; p ++)
   69         {
   70             int channel = ports * i + p;
   71 
   72             Index<float> & in = loaded.in_bufs[channel];
   73             in.insert (0, LADSPA_BUFLEN);
   74             desc.connect_port (handle, plugin.in_ports[p], in.begin ());
   75 
   76             Index<float> & out = loaded.out_bufs[channel];
   77             out.insert (0, LADSPA_BUFLEN);
   78             desc.connect_port (handle, plugin.out_ports[p], out.begin ());
   79         }
   80 
   81         if (desc.activate)
   82             desc.activate (handle);
   83     }
   84 }
   85 
   86 static void run_plugin (LoadedPlugin & loaded, float * data, int samples)
   87 {
   88     if (! loaded.instances.len ())
   89         return;
   90 
   91     PluginData & plugin = loaded.plugin;
   92     const LADSPA_Descriptor & desc = plugin.desc;
   93 
   94     int ports = plugin.in_ports.len ();
   95     int instances = loaded.instances.len ();
   96     assert (ports * instances == ladspa_channels);
   97 
   98     while (samples / ladspa_channels > 0)
   99     {
  100         int frames = aud::min (samples / ladspa_channels, LADSPA_BUFLEN);
  101 
  102         for (int i = 0; i < instances; i ++)
  103         {
  104             LADSPA_Handle handle = loaded.instances[i];
  105 
  106             for (int p = 0; p < ports; p ++)
  107             {
  108                 int channel = ports * i + p;
  109                 float * get = data + channel;
  110                 float * in = loaded.in_bufs[channel].begin ();
  111                 float * in_end = in + frames;
  112 
  113                 while (in < in_end)
  114                 {
  115                     * in ++ = * get;
  116                     get += ladspa_channels;
  117                 }
  118             }
  119 
  120             desc.run (handle, frames);
  121 
  122             for (int p = 0; p < ports; p ++)
  123             {
  124                 int channel = ports * i + p;
  125                 float * set = data + channel;
  126                 float * out = loaded.out_bufs[channel].begin ();
  127                 float * out_end = out + frames;
  128 
  129                 while (out < out_end)
  130                 {
  131                     * set = * out ++;
  132                     set += ladspa_channels;
  133                 }
  134             }
  135         }
  136 
  137         data += ladspa_channels * frames;
  138         samples -= ladspa_channels * frames;
  139     }
  140 }
  141 
  142 static void flush_plugin (LoadedPlugin & loaded)
  143 {
  144     if (! loaded.instances.len ())
  145         return;
  146 
  147     PluginData & plugin = loaded.plugin;
  148     const LADSPA_Descriptor & desc = plugin.desc;
  149 
  150     int instances = loaded.instances.len ();
  151     for (int i = 0; i < instances; i ++)
  152     {
  153         LADSPA_Handle handle = loaded.instances[i];
  154 
  155         if (desc.deactivate)
  156             desc.deactivate (handle);
  157         if (desc.activate)
  158             desc.activate (handle);
  159     }
  160 }
  161 
  162 void shutdown_plugin_locked (LoadedPlugin & loaded)
  163 {
  164     loaded.active = 0;
  165 
  166     if (! loaded.instances.len ())
  167         return;
  168 
  169     PluginData & plugin = loaded.plugin;
  170     const LADSPA_Descriptor & desc = plugin.desc;
  171 
  172     int instances = loaded.instances.len ();
  173     for (int i = 0; i < instances; i ++)
  174     {
  175         LADSPA_Handle handle = loaded.instances[i];
  176 
  177         if (desc.deactivate)
  178             desc.deactivate (handle);
  179 
  180         desc.cleanup (handle);
  181     }
  182 
  183     loaded.instances.clear ();
  184     loaded.in_bufs.clear ();
  185     loaded.out_bufs.clear ();
  186 }
  187 
  188 void LADSPAHost::start (int & channels, int & rate)
  189 {
  190     pthread_mutex_lock (& mutex);
  191 
  192     for (auto & loaded : loadeds)
  193         shutdown_plugin_locked (* loaded);
  194 
  195     ladspa_channels = channels;
  196     ladspa_rate = rate;
  197 
  198     pthread_mutex_unlock (& mutex);
  199 }
  200 
  201 Index<float> & LADSPAHost::process (Index<float> & data)
  202 {
  203     pthread_mutex_lock (& mutex);
  204 
  205     for (auto & loaded : loadeds)
  206     {
  207         start_plugin (* loaded);
  208         run_plugin (* loaded, data.begin (), data.len ());
  209     }
  210 
  211     pthread_mutex_unlock (& mutex);
  212     return data;
  213 }
  214 
  215 bool LADSPAHost::flush (bool force)
  216 {
  217     pthread_mutex_lock (& mutex);
  218 
  219     for (auto & loaded : loadeds)
  220         flush_plugin (* loaded);
  221 
  222     pthread_mutex_unlock (& mutex);
  223     return true;
  224 }
  225 
  226 Index<float> & LADSPAHost::finish (Index<float> & data, bool end_of_playlist)
  227 {
  228     pthread_mutex_lock (& mutex);
  229 
  230     for (auto & loaded : loadeds)
  231     {
  232         start_plugin (* loaded);
  233         run_plugin (* loaded, data.begin (), data.len ());
  234 
  235         if (end_of_playlist)
  236             shutdown_plugin_locked (* loaded);
  237     }
  238 
  239     pthread_mutex_unlock (& mutex);
  240     return data;
  241 }