RE: [linux-audio-dev] extending LADSPA,

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: RE: [linux-audio-dev] extending LADSPA,
From: Paul Sladen (paul_AT_sladen.org)
Date: Fri Oct 27 2000 - 14:48:35 EEST


Ok, I've not studied the LADSPA API, but partly on purpose, because of
what I'm working on; but this seems to answer and enable everything that
people have asked for.

The basic idea is that the plugin is passed not only a memory location and
length, but /also/ it's location within a larger buffer.

For Streaming/Realtime, the "bigger buffer" with be the same length as the
selection for modifications to be made, though quite possibley the selection
may be placed at the end of a slightly larger "bigger buffer", to allow
better support to plugins wanting to use the previous values as extra
parameters for interpolation or reverb algoritoms.

Anyway, there are two plugins below, one demostration "interpolated gain",
ie, a volume/fade plugin, and a second [much shorter] one demostrating
"reverse".

The plugin not only supports just passing "begin" and "end" gain parameters,
but also using a "gain map", which for those who now 3d graphics, it is
analogous to a "light map" being multipled by it's "texture map".

It is still not well-enough defined to be useable, but hopefully you get
it idea.

Anyway, IIRC, this is my first post to LAD, so enjoy:

Paul

--
e: paul_AT_sladen.org   t: 0115 922 7162

-*-

<?xml version="1.0" ?> <pluginapi version="1.0"> <plugin interface="1.0" name="reverse" hint="Reverse Area">

<stream direction="in" enum="1" format="float32v" required="yes" name="AudioIn" hint="Source Audio"/> <stream direction="out" enum="2" format="float32v" required="yes" name="AudioOut" hint="Processed Audio"/>

<code language="c" libraries="-lm">

#include "plugin-v1.h" #include <math.h>

typedef struct tagStream { float *start; size_t length; size_t offset; size_t select; } stream;

static stream in, out;

<run name="run_no_checking" validating="none">

int run_no_checking(void) { int i; float *inp, *outp; size_t length; length = out.select - out.offset; inp = in.buffer + in.length - out.offset; outp = out.buffer + out.offset;

for (i=0; i &lt; length; i++) *outp++ = *inp--;

return PLUGIN_OK; } </run>

<setstream format="float32v" function="set_stream_f32v">

int set_stream_f32v(enum stream, float *pointer, size_t length, size_t selection_offset, size_t selection_length) { switch(stream) { case 1: // Input Channel in.buffer = pointer; in.length = length; in.offset = selection_offset; in.select = selection_length; break; case 2: // Output Channel out.buffer = pointer; out.length = length; out.offset = selection_offset; out.select = selection_length; break; default: return PLUGIN_PARAM_ERROR; } return PLUGIN_OK; }

</setstream> </code> </plugin>

<!-- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -->

<plugin interface="1.0" name="gain" hint="Interpolated Fade">

<stream direction="in" enum="1" format="float32v" required="yes" name="AudioIn" hint="Source Audio"/> <stream direction="out" enum="2" format="float32v" required="yes" name="AudioOut" hint="Processed Audio"/>

<stream direction="in" enum="6" format="float32v" required="MapEnable" name="GainMap" hint="Gain Ramping Map"/>

<stream direction="in" enum="3" format="float32" required="yes" name="StartGain" hint="Start Gain"/>

<stream direction="in" enum="4" format="float32" required="Interpolate" name="EndGain" hint="End Gain"/>

<stream direction="in" enum="5" format="bool" required="optional" name="Interpolate" hint="Linear Gain Interpolation"/> <stream direction="in" enum="7" format="bool" required="optional" name="MapEnable" hint="Gain Map Enable"/>

<code language="c" libraries="-lm">

#include "plugin-v1.h" #include <math.h>

typedef struct tagStream { float *start; size_t length; size_t offset; size_t select; } stream;

static stream in, out, map; float volume_start, volume_end; int interpolate, gain_map;

<!-- The Idea here is that both "fast", and "slow" versions can be present, for instance a version of this function should be supplied that also validates/caps the selection values to make sure that they are within the total length of the buffer. -->

<run name="run_no_checking" validating="none">

int run_no_checking(void) { size_t i, length; float volume, volume2, volume_dx; float *inp, *outp, *mapp;

/* This is fundamentally /wrong/, each different stream should be nicely interpolated between ".offset" and ".select", since the host is passing a start and finish parameters, the least that we can do is to honour them... for instance, the Gain Map is unlikely to be the same length as the input stream selection. And it is much more likely to be shorter. Think "Light Maps" being multipled with a "Texture" in 3d Graphics. */

length = out.select - out.offset; inp = in.buffer + in.offset; outp = out.buffer + out.offset; mapp = map.buffer + map.offset;

if(!map_enable) { if(interpolate) volume_dx = (volume2 - volume) / (float)length; else volume_dx = 0.0;

for (i = 0; i &lt; length; i++, volume += volume_dx ) *outp++ = *inp++ * volume; } else { if(interpolate) volume_dx = (volume2 - volume) / (float)length; else volume_dx = 0.0;

for (i = 0; i &lt; length; i++, volume += volume_dx ) *outp++ = *inp++ * *mapp++ * volume; }

return PLUGIN_OK; } </run>

<setstream format="float32v" function="set_stream_f32v">

int set_stream_f32v(enum stream, float *pointer, size_t length, size_t selection_offset, size_t selection_length) { switch(stream) { case 1: // Input Channel in.buffer = pointer; in.length = length; in.offset = selection_offset; in.select = selection_length; break; case 2: // Output Channel out.buffer = pointer; out.length = length; out.offset = selection_offset; out.select = selection_length; break; case 6: // Gain Map Channel map.buffer = pointer; map.length = length; map.offset = selection_offset; map.select = selection_length; break; default: return PLUGIN_PARAM_ERROR; } return PLUGIN_OK; }

</setstream> <setstream format="float32" function="set_stream_f32">

int set_stream_f32(enum stream, float *pointer, size_t length, size_t selection_offset, size_t selection_length) { switch(stream) { case 3: // Start Volume volume_start = pow(pointer[selection_offset]/20, 10); break; case 4: // Start Volume volume_end = pow(pointer[selection_offset]/20, 10); break; case 5: // Interpolate if(pointer[selection_offset] != 0.0) interpolate = 1; break; case 7: // Gain Map if(pointer[selection_offset] != 0.0) map_enable = 1; break; default: return PLUGIN_PARAM_ERROR; } return PLUGIN_OK; } </setstream> <setstream format="bool" function="set_stream_bool">

int set_stream_bool(enum stream, int *pointer, size_t length, size_t selection_offset, size_t selection_length) { switch(stream) { case 5: // Interpolate if(pointer[selection_offset] != 0) interpolate = 1; break; case 7: // Gain Map if(pointer[selection_offset] != 0) map_enable = 1; break; default: return PLUGIN_PARAM_ERROR; } return PLUGIN_OK; } </setstream> </code> </plugin>

</pluginapi>


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Fri Oct 27 2000 - 16:51:14 EEST