Develop a softsynth with LV2

Programming applications for making music on Linux.

Moderators: MattKingUSA, khz

Post Reply
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Develop a softsynth with LV2

Post by f00bar »

I am trying to implement an LV2 softsynth

main.cpp

#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
#include <lv2/lv2plug.in/ns/ext/atom/util.h>
#include <lv2/lv2plug.in/ns/ext/midi/midi.h>
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
#include <lv2/lv2plug.in/ns/lv2core/lv2.h>

struct Fatsaw
{
const LV2_Atom_Sequence* midi_in;
float* output_L;
float* output_R;
};

static const char* URI="http://example.org/fatsaw";

static LV2_Handle instanceCreate(const LV2_Descriptor* descriptor,double rate
,const char* bundle_path,const LV2_Feature* const* features)
{
return new Fatsaw;
}

static void portConnect(LV2_Handle fatsaw,uint32_t port,void* data)
{
Fatsaw* obj=(Fatsaw*)fatsaw;
switch(port)
{
case 0:
obj->midi_in=(const LV2_Atom_Sequence*)data;
break;
case 1:
obj->output_L=(float*)data;
break;
case 2:
obj->output_R=(float*)data;
break;
}
}

static void activate(LV2_Handle fatsaw)
{

}

static void process(LV2_Handle fatsaw, uint32_t n_samples)
{
// Write code here
}

static void deactivate(LV2_Handle fatsaw)
{
}

static void instanceDestroy(LV2_Handle fatsaw)
{
Fatsaw* obj=(Fatsaw*)fatsaw;
delete obj;
}

static const void* extensionDataGet(const char* uri)
{return nullptr;}

static const LV2_Descriptor descriptor =
{
URI,
instanceCreate,
portConnect,
activate,
process,
deactivate,
instanceDestroy,
extensionDataGet
};

LV2_SYMBOL_EXPORT const LV2_Descriptor* lv2_descriptor(uint32_t index)
{
switch (index)
{
case 0:
return &descriptor;
default:
return nullptr;
}
}

manifest.ttl

@prefix atom: <http://lv2plug.in/ns/ext/atom#> .
@prefix doap: <http://usefulinc.com/ns/doap#> .
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
@prefix midi: <http://lv2plug.in/ns/ext/midi#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .

<http://example.org/fatsaw>
a lv2:Plugin;
lv2:binary <fatsaw.so>;
doap:name "Fatsaw";
doap:license <http://usefulinc.com/doap/licenses/gpl>;


lv2:port
[
a lv2:InputPort,atom:AtomPort;
lv2:index 1;
lv2:symbol "midi_in";
lv2:name "MIDI in";
],
[
a lv2:OutputPort,lv2:AudioPort;
lv2:index 1;
lv2:symbol "output_L";
lv2:name "Output L";
],
[
a lv2:OutputPort,lv2:AudioPort;
lv2:index 2;
lv2:symbol "output_R";
lv2:name "Output R";
].

g++ main.cpp -shared -fpic -std=c++11 -o fatsaw.so
cp * $HOME/.lv2/fatsaw.lv2


Ardour claims it is invalid. What is missing?

I want to implement a clone of TrancsenderSE. This synth has 10 detuned sawtooth/squarewave oscillators + 5 oscillators one octave down. The envelope controls a LP filter. To get the thing working, the plug-in has to know the current beat, because the gate produces a rythm pattern. BTW the lv2 docs could have been better.
ssj71
Established Member
Posts: 1294
Joined: Tue Sep 25, 2012 6:36 pm
Has thanked: 1 time

Re: Develop a softsynth with LV2

Post by ssj71 »

hmm. I don't see anything blatantly wrong, but I'm not an expert. I just copied other people's plugin ttl when I made my synth plugin. You would probably do well to test using jalv rather than ardour while you're just getting started. It might give a bit more verbose error message. Falktx also has made a program that installs with carla that will scan/validate your ttl . Sorry I can't help more.
EDIT, if you do IRC hop onto #lad and you might get help a bit faster.
_ssj71

music: https://soundcloud.com/ssj71
My plugins are Infamous! http://ssj71.github.io/infamousPlugins
I just want to get back to making music!
tramp
Established Member
Posts: 2348
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 468 times

Re: Develop a softsynth with LV2

Post by tramp »

along with the manifest.ttl, you need a fatsaw.ttl
in the manifest you only point to the library witch contain your plug, the description comes in the fatsaw.ttl.
here is a example synth
http://lv2plug.in/browser/trunk/plugins ... order=name
On the road again.
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Develop a softsynth with LV2

Post by f00bar »

tramp wrote:along with the manifest.ttl, you need a fatsaw.ttl
in the manifest you only point to the library witch contain your plug, the description comes in the fatsaw.ttl.
here is a example synth
http://lv2plug.in/browser/trunk/plugins ... order=name
That is just convention, but it is a good idea to give each port a uniq number in the ttl file (was 1 1 2 inseat of 0 1 2).
User avatar
sysrqer
Established Member
Posts: 2527
Joined: Thu Nov 14, 2013 11:47 pm
Has thanked: 320 times
Been thanked: 153 times
Contact:

Re: Develop a softsynth with LV2

Post by sysrqer »

falkTX, I don't want to derail the thread but just to say thank you for posting that, they look amazing. Do you know if the vst builds with those if it is enabled?
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Develop a softsynth with LV2

Post by f00bar »

falkTX, can you give a short introduction to your build system. Is it just copying the plugins directory and clear all sub-directories?
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Develop a softsynth with LV2

Post by f00bar »

So I define a macro, then I get a different backend. But I need timepos for trigging the trance gate.

#if DISTRHO_PLUGIN_WANT_TIMEPOS
# warning LV2 TimePos still TODO
#endif
tramp
Established Member
Posts: 2348
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 468 times

Re: Develop a softsynth with LV2

Post by tramp »

f00bar wrote:
tramp wrote:along with the manifest.ttl, you need a fatsaw.ttl
in the manifest you only point to the library witch contain your plug, the description comes in the fatsaw.ttl.
here is a example synth
http://lv2plug.in/browser/trunk/plugins ... order=name
That is just convention, . . .
This is true for .h / .hpp files as well. :lol:
On the road again.
f00bar
Established Member
Posts: 83
Joined: Sun May 12, 2013 7:40 pm

Re: Develop a softsynth with LV2

Post by f00bar »

falkTX wrote:
f00bar wrote:So I define a macro, then I get a different backend. But I need timepos for trigging the trance gate.

#if DISTRHO_PLUGIN_WANT_TIMEPOS
# warning LV2 TimePos still TODO
#endif
The basic LV2 time stuff is done, but no one made a plugin that needed it until now.
if you look at the code, the missing bits are:

Code: Select all

// TODO:
// - tick
// - barStartTick
// - ticksPerBeat
the other stuff on the TimePos struct is already working.
Do you need any of those 3 in the TODO?
I do need to know where to start the gate sequence. So as long as there is a reference framecount where I know the values of beat and tick, it is fine.
Post Reply