High abstraction level audio plugins specification (and code generation)

Download PDF

If you ever wrote at least 2 audio plugins in your life, for sure you have noticed you had to write a lot of duplicated code. In other words, most of the times, writing a plugin there is very little entropy from your code.

My first approach to this problem was some years ago when i did a simple code generator of the base code of a clam plugin (see these clam-devel threads for more info ‘Commit #11195: templated plugins generator‘ and ‘Frontend for automatic generation of plugin code‘)

Now i’m with a simple but i think powerful project (derived from the needs i noticed at club de audio de la fiuba) to have an application to generate code of different standards using XML based specifications. Then, as before, you nearly only need to write the signal processing code of the plugin (and can forget about the mechanical work).

The idea is to get VST, LADSPA, lv2, CLAM, Audio Units and possibly others standards base code ready to compile for different operating systems and using different build systems. Indeed, once finished, will be easy to implement new modules for others plugins specifications since will consist only into implement an interface.

My proposed xml specification (comments and suggestions are welcome!), showed as a clam plugin definition example is here. Basically contains metadata, input and output ports and controls and other build definitions:

< ?xml version="1.0" encoding="UTF-8"?>
< !DOCTYPE AudioPlugin SYSTEM "AudioPluginDef.dtd">
<audioplugin Version="0.1">
        <metadata>
                <name>TestRtPlugin</name>
                <description>This is a test realtime audio plugin</description>
                <authors>Fulano, Sultano, Mengano</authors>
                <copyright Year="2010">Club de Audio FIUBA</copyright>
                <license>GPL</license>
                <category>Plugins</category>
        </metadata>

        <inputs>
                <port Name="L Input">AudioInPort</port>
                <port Name="R Input">AudioInPort</port>

                <control Name="Gain" Min="0." Max="1.0" DefaultValue=".5">InControlFloat</control>
        </inputs>

        <outputs>
                <port Name="L Output">AudioOutPort</port>
                <port Name="R Output">AudioOutPort</port>
        </outputs>

        <outputplugin Standard="CLAM" BuildSystem="Scons" OS="Linux">
                <basetemplatename>Default</basetemplatename>

                <clam_defaultconfig> <!--  CLAM plugin specific configuration -->
                        <baseclass>Processing</baseclass>
                        <withconfig>True</withconfig>
                </clam_defaultconfig>
        </outputplugin>
</audioplugin>

I also thought about an UID (Uniqued ID) field at metadata, there is not showed in the example since is not needed to clam plugins.

There is also a .dtd file to check the correctness of the plugin spec.

Posted in ideas, plugins, programming | Tagged , , , , , , , , , , , , | 2 Comments

Some experience with CLAM inside an audio club at FIUBA, Argentina

Download PDF

(Note: I wrote this as something to tell to the clam-devel mailing list about some of my source-code commits)

About eight months ago, there was a foundation of something like an “audio club” in my university [1]. As soon i learned about that, i quickly got in touch with them and noticed that there was a major interest in analog issues (the only audio area with at least elective, courses in the university). So i told them about all the cool things that are available and ready to do with digital audio, mostly signal processing related. I talked in general, but of course i also talked about clam, with all its prototyping, real-time and easy development of plugins features. Even many of them ended installing and using it, and some even developing with more or less help. One thing to notice is that most of them are students from first years and most (but not all) are students with a basic programming level (because they are from electronics) but strong dsp knowledge (behind this is an university with more emphasis in theory than practice)
We started specifying plugins from a more abstract level (inputs/outputs/controls) and generating the source code base using
CLAM’s Templated Plugins Code Generator [2] and prototyping some simple applications. But one of the things we ended up doing was to take advantage of clam as platform to prototype medic related applications like filter ECG signal from noise in realtime, and some like _vice-versa_, i mean applying some processing knowledge from that area to audio.

Some of that work (one hour per week average) it’s now in the repo, most remarkable i think are filters work, by above the adaptative notch one (which even was used as a demo of a talk of one of the members about the steepest descent algorithm and its application to filter ECG signals)

Some development screenshots:
http://clam-project.org/wiki/Image:FilterByCoefExample.jpg
http://clam-project.org/wiki/Image:FilterExample-LP-HP.jpg
http://clam-project.org/wiki/Image:ThreeBandFilterOutputWithWhiteNoiseAsInput.jpg
http://clam-project.org/wiki/Image:GaussianWhiteNoiseHistogram.jpg
http://clam-project.org/wiki/Image:UniformWhiteNoiseHistogram.jpg

[0] FIUBA: Engineering Faculty of Buenos Aires University
[1] Group: http://code.google.com/p/club-audio-fiuba
Source code repo: http://groups.google.com/group/club_de_audio_fiuba
[2] http://audiores.uint8.com.ar/blog/2009/08/17/showing-a-little-about-clam-as-a-prototyping-tool-at-the-audio-club-of-fiuba/

Posted in CLAM, ClubAudioFiuba | Tagged , , , , , , , , , , , , , , , , , , , | Leave a comment

Showing a little about CLAM as a prototyping tool at the Audio Club of FIUBA

Download PDF

Last week, at the recent ‘audio club’ of my university, I was showing how to work with the CLAM framework as a tool to prototype realtime audio signal processing applications in a simple and fast way.

We started with an example network to show some about the NetworkEditor capabilities: karaoke.clamnetwork
Karaoke

After that, we continue with a simple ‘diodo distortion’ plugin:

We specified and generated the source code base in this way:
Especificación de distorsión tipo diodo

We wrote this code:

        bool Do()
        {
            bool result = Do( mEntrada.GetAudio(), mSalida.GetAudio() );

            mEntrada.Consume();
            mSalida.Produce();

            return result;
        }
   
        bool Do(const Audio& in, Audio& out)
        {
            int size = in.GetSize();

            const DataArray& inb = in.GetBuffer();
            DataArray& outb = out.GetBuffer();

            for (int i=0;i< size;i++)
            {
                if ( fabs(inb[i])>0.8 )
                    outb[i] = inb[i]&lt;0.? -0.8:0.8;
                else
                    outb[i] = inb[i];
            }
            return true;
        }

And built this net to try it:
Red para probar distorsión de diodo

The source code of the plugin ready to be compiled is here: pluginDistorsiónDiodo_ClubAudioFiuba.tar.gz

As extra, I leave here pluginDistorsiónDiodoConControlDeClipping_ClubAudioFiuba.tar.gz the same diode distortion, but with a clipping control to set the threshold when playing.

They liked these kind of prototyping features a lot, so probably we’re going to keep using it at the club.

Posted in CLAM, ClubAudioFiuba | Tagged , , , , , , , | 1 Comment

Interactive CLAM programming (with python)

Download PDF

Recently I been playing with python bindings for the CLAM library. Here is a demo demonstrating how to interactively build a network and play a file using the IPython shell:

 
Related scripts: playfile.py fft_example.py.
 
PyCLAM source. INSTALL.

Posted in CLAM, ideas, python, screencast | Tagged , , , , , , , , , , , | Leave a comment

CLAM processing generator script (example of use)

Download PDF

This script is about a basic code generation of a CLAM plugin. In some point I think this is some kind of meta-programming or perhaps the term “automatic programming” fits better. The basic idea is to specify some basic features of the planned new processing in a plain text and then, generate some code with the script, saving in this way many of the often repetitive and mechanical work needed to set-up a new processing from scratch. Main intention is to allow concentrate in the Do() function or plugin details quickly.

As an example, I will reproduce here how I worked with me some time ago:
 
One day, in the irc #clam channel:
“[11:51] <groton> Consul, do you know if there is any trigger-like processing unit, list when the volume gets louder than a threshold or something like that”

I’m not Consul in the irc (I’m hordia), but next day at my console…

cd CLAM/scripts/TemplatedPluginsGenerator
vi ThresholdTrigger.template

Name:ThresholdTriggerTemplate
BaseClass:Processing
i:AudioInPort,Audio Input
ic:0,1,Threshold
oc:0,1,Trigger

In words, this means a Processing template named “ThresholdTriggerTemplate” using “Processing” as a base class and with one input of “AudioInPort” type named “Audio Input”, with one in control in the 0..1 range named “Threshold” and one out control named “Trigger”. Of course, you can add as many inputs/outputs of ports or controls as you want.
 

This script creates the template:

./TemplateGenerator.py ThresholdTrigger.template

 
And this one the processing plugin:

./TemplatedPluginsGenerator.py ThresholdTrigger ThresholdTriggerTemplate "Hernán Ordiales" GPL 2008

Again in words, this means create a new processing called “ThresholdTrigger” based on the “ThresholdTriggerTemplate” filling the copyright with my name plus the current year and the license with the GPL text.

 
A final edit just typing the required code for the Do() function:

cd CLAM/plugins/ThresholdTrigger
vi ThresholdTrigger.hxx

#include <cmath>

bool Do()
{
       bool result = Do( mAudioInput.GetAudio() );
       mAudioInput.Consume();
       return result;
}

bool Do(const Audio& in)
{
       int size = in.GetSize();
       const DataArray& inb = in.GetBuffer();
       TData threshold = mThreshold.GetLastValue();
       bool trigger = 0;
       for (int i=0;i<size ;i++)
       {
               if (std::fabs(inb[i])>threshold)
                       trigger = 1;
       }
       mTrigger.SendControl(trigger);
       return true;
}
</size></cmath>

At this point, just remains add the basic SConstruct file for a CLAM plugin, compile it with the corresponding clam_prefix and install it:

scons install clam_prefix=$CLAM_PATH
NetworkEditor

And ready to use…

This example it’s very simple and has a poor implementation but was just to show the idea of how those scripts can save a lot of work.

Update: I made a frontend for these scripts: ProcessingCodeGenerator

Posted in CLAM, plugins, programming, python | Tagged , , , , , , , | 1 Comment

Distortion rack prototype

Download PDF

A nice prototype:

CLAM distortion rack prototype

 
 

And the net behind:

CLAM distortion rack prototype

Posted in CLAM, prototype | Tagged , , , , | 1 Comment

LADSPA versions of my recent simple distortions

Download PDF

After prototype different kind of simple distortions in NetworkEditor i managed to port all them to ladspa plugins. Despite the fact that the task was less difficult than i had expected at first, prototype with CLAM first worth a lot. Probably, if i had begun coding directly to ladspa source, reach the same status would be taken to me 10 or more times more. I think also was very interesting as “development process”, instead of modeling for example with matlab, you could easy modeling (among other things) in CLAM, and then, if you want/need make your final product by your own.

More, the other day i learned that is already possible to compile ladspa plugins directly from CLAM networks… very cool! Though i think this feature is not completely ready yet and i’m still have to dig in it, i don’t think that i have lost time porting manually because now i have a better knowledge and understanding about ladspa specification that for sure will be useful to work with this (for me “new”) feature, that probably needs some fixes.

About the ladspa plugins programming, i just downloaded the sdk from ladspa.org, read some of the ladspa.h file and some basic examples (the ones from sdk) and that was enough to handle the basis. Ah, i had to ask for some ladspa ID’s for my plugins here: ladspa at muse.demon.co.uk

On the other hand i’ve forwarded my distortion examples to musix distro folks and some of them indeed have tried it and made a couple of jack-rack presets and audio demos. More info about this here: DSP-es#Presets, ogg demos and jack-rack presets, and patchs review.

Next step (in my TODO list): produce ladspa binaries directly from CLAM networks.

I have uploaded these plugins here: disthordian ladspa plugins.

Posted in plugins | Tagged , , , , , , , , , , | Leave a comment

New CLAM plugin: (‘very’ for now) simple guitar distortion

Download PDF

A week or more ago, Daniel Vidal Chornet (collaborator of Musix) asked me if i can develop guitar distortion effects, because he couldn’t find something decent that suits his needs, i said “sadly i have no idea about distortions effects and anyway i have no time right now to do that”, but then i remembered how useful could be the clam framework and i tried to do a little spike about. Results were better than i had expected at first (is not a super cool distortion, but at least sound like one).

Basically i merged and tweaked a couple of simple/base algorithms found in the web for distortion and compression and in less than 30 minutes i had something working and sounds like a guitar distortion (“clean” ones seems to sound better easily). I was amazed how fast and easy (develop and test in clam/networkeditor, once you get the basis) was. I think right now is far to be a good distortion, but as learning process and first demo seems very good.

Here some sound examples:

Original: [audio:http://audiores.uint8.com.ar/files/audios/guitardist/dvlc-guitar.mp3]
(dvlc-guitar.ogg)

With distortion: [audio:http://audiores.uint8.com.ar/files/audios/guitardist/guitardist-ex1.mp3]
(guitardist-ex1.ogg)

Test network looks like:

Distortion NE network

 

The source code is here (as NetworkEditor plugin): GuitarDistortion.tar.gz

Some optional tweaks could include add a three band filter but i’m still not sure if it’s better to put it at first or at the end.

Special thanks for testing and audio samples to Daniel Vidal Chornet. I should take from my closet my fender stratocaster and do my own samples :-D . OTOH, we already arrange to do a remote gig with this.

Another useful NetworkEditor processings plugins i had made during this “work”:

  • AutomaticGainControl: Adaptative automatic gain control. Given an output reference and step response adjusts the output volume to keep it constant (AutomaticGainControl.tar.gz)
  • AudioSwitch: Switchs between a configurable amount of inputs (like a multiplexer) (AudioSwitch.tar.gz)

 
Related: LADSPA versions of my recent simple distortions
Update: Distortion rack prototype

Posted in CLAM, plugins | Tagged , , , , , , , , , , | 6 Comments

My presentation at the “VI Jornadas de Acústica, Electroacústica y áreas vinculadas (CADAE)”

Download PDF

Yesterday I had the opportunity to give a talk about my recent work in the google summer of code at the VI Jornadas de Acústica, Electroacústica y áreas vinculadas (CADAE). The given time was short, so was a little hard to explain all in only 20 minutes, but seems that all went well (at least seemed like the people). Here is my presentation (in Spanish):

 

Transformaciones espectrales en tiempo real para CLAM

 

Download: Transformaciones espectrales en tiempo real para CLAM.pdf

 

Posted in CLAM, GSoC2007, conferences, dissertation, events | Tagged , , , , , , , , , , , , , , , , , , | Leave a comment

Fundamental (in Hz) to a MIDI note

Download PDF

Working to have audio-to-midi in NetworkEditor (CLAM) I needed to convert a fundamental frequency value to a MIDI note one.

I found some source code related with this in Voice2MIDI app, but was not explained at all, so looking for the reason of that formula I arrived at this:

Knowing about equal-tempered scale (check this) and $latex 2^{\frac{n}{12}}$ relation between frequencies plus the fact that C4 or “middle c” has a MIDI value of 60, it’s easy to conclude that then A4 (which its frequency value is 440Hz, a standard for tunning and is 9 semi-tones more) has a MIDI value of 69.

 

Then, starting with:
fundfrec = 440Hz * 2^{(\frac{1}{12})^n}

 

It’s easy to arrive at this:
fund_{midinote} = 69+log_{2^{(\frac{1}{12})}}(\frac{fundfrec}{440Hz})

 

and then, also taking in account this mathematical relation::
log_{2^{\frac{1}{12}}}(a) = log_{e}(a)*17.31234

 

the final formula looks like:
fund_{midinote} = 69+log_{e}(\frac{fundfrec}{440Hz})*17.31234

 

and a final c++ code like:

fund_midinote = round( 69. + log(fundfrec/440.)*17.31234 );

 
Related post: nictuku’s inverse formula (i.e. from MIDI to Hz) here “Translanting MIDI Notes to frequencies in the diatonic scale using the central A (440hz) as reference“.

Posted in CLAM, GSoC2007, math, midi | Tagged , , , , , , , , , , | Leave a comment