AP-Gen new release (LADSPA and VST support)

AP-Gen speeds up and eases the plugin development through base source code generation, both for different standards and operating systems, thus achieving that the developer can focus on his goal, the digital audio processing.

To achieve this, starts from normalized definitions and uses a template engine. These definitions could be general abstractions of the plugin, like amount and type of inputs and outputs of data or controls, or more specific ones, like the kind of the build system, metadata and even details of each architecture. On the other hand, the templates are the elements that maintain the common features of each standard.

The advantage of this way of working is that, once high level aspects are established, next step can be to develop the signal processing function. Leaving aside, among other things, all the repetitive work of writing library code, programming language or current standard details, and each architecture compilation issues.

Support to new standards can be added in a modular form.

AP-Gen V.014.zip

News:
* LADSPA support added.

Features:
* VST support (native and cross-compiled in linux with mingw).
* LADSPA support.
* Plugin generation examples for vst, ladspa and clam.

Posted in English, audio, plugins, programming | Leave a comment

VST cross compiling in Linux

1. Install mingw32 and wine:
$ sudo apt-get install mingw32
$ sudo apt-get install wine

2. Download Steinberg VST SDK 2.4 and unzip it.

3. Create a PLUGIN_NAME.def file:

LIBRARY     ''
DESCRIPTION ''
EXPORTS     main=VSTPluginMain

4. Create a Makefile like this one:

# change this to the location of your unpacked VST SDK:
VSTSDKDIR = ../../vstsdk2.4

# Change the plugin name here (same name than .h file)
PLUGIN_NAME = PLUGIN_NAME

CPP       = i586-mingw32msvc-g++

VST_OBJ = $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o

OBJ       = $(PLUGIN_NAME).o $(VST_OBJ)

LIBS      = -L. --add-stdcall-alias -lole32 -lkernel32 -lgdi32 -luuid -luser32 -mwindows --no-export-all-symbols --def $(PLUGIN_NAME).def

CXXINCS   = -I"$(VSTSDKDIR)/pluginterfaces/vst2.x" -I"$(VSTSDKDIR)/public.sdk/source/vst2.x" -I"$(VSTSDKDIR)" -I"$(VSTSDKDIR)/vstgui.sf/vstgui" -I.
BIN       = $(PLUGIN_NAME).dll
CXXFLAGS  = $(CXXINCS) -DBUILDING_DLL=1 -mwindows -O3
RM        = rm -f

.PHONY: all clean

all: $(PLUGIN_NAME).dll

clean:
  ${RM} $(OBJ) $(BIN)

# not we're using mingw dllwrap tool
DLLWRAP   = i586-mingw32msvc-dllwrap

DEFFILE   = lib$(PLUGIN_NAME).def

STATICLIB = lib$(PLUGIN_NAME).a

$(BIN): $(OBJ)
  # note the --driver-name is equal to the compiler executable name for mingw
  $(DLLWRAP) --output-def $(DEFFILE) --driver-name $(CPP) --implib $(STATICLIB) $(OBJ) $(LIBS) -o $(BIN)

%.o: %.cpp
  $(CPP) -c $< -o $@ $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.cpp
  $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.cpp
  $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.cpp
  $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o $(CXXFLAGS)

5. Compile it. Run make in the base dir of your project.

6. Try it. Load the generated .dll file in a vst host (like this one)

Alternatively use AP-Gen to easy all the process: http://code.google.com/p/ap-gen/

AP-Gen speeds up and eases the plugin development through base source code generation, both for different standards and operating systems, thus achieving that the developer can focus on his goal, the digital audio processing.

Just write the definition file and run something like this:

$  ./ap-gen.py examples/vst-example-plugin-def.xml

Good luck.

Posted in English, GNU/Linux, audio, free software, plugins, specifications, standards | Leave a comment

Reasons to not use locks: Priority inversion and general purpose vs realtime OS

“Let’s say your GUI thread is holding a shared lock when the audio callback runs. In order for your audio callback to return the buffer on time it first needs to wait for your GUI thread to release the lock. Your GUI thread will be running with a much lower priority than the audio thread, so it could be interrupted by pretty much any other process on the system, and the callback will have to first wait for this other process, and then the GUI thread to finish and release the lock before the audio callback can finish computing the buffer — even though the audio thread may have the highest priority on the system. This is called priority inversion.”

“Real-time operating systems implement special mechanisms to avoid priority inversion. For example by temporarily elevating the priority of the lock holder to the priority of the highest thread waiting for the lock. On Linux this is available by using a patched kernel with the the RT preempt patch. But if you want your code to be portable to all general purpose operating systems, then you can’t rely on real-time OS features like priority inheritance protocols.”

(Update: On Linux, user-space priority inheritance mutexes (PTHREAD_PRIO_INHERIT) have been available since kernel version 2.6.18 together with Glibc 2.5. Released September 19, 2006. Used in Debian 4.0 etch, 8 April 2007. Thanks to Helge for pointing this out in the comments.)

Realtime programming and more reasons to not use locks: http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

Posted in English, audio, programming | 2 Comments

High abstraction level audio plugins specification (and code generation)

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

(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

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)

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)

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

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

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