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.
Develop a softsynth with LV2
Moderators: MattKingUSA, khz
Re: Develop a softsynth with LV2
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.
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!
music: https://soundcloud.com/ssj71
My plugins are Infamous! http://ssj71.github.io/infamousPlugins
I just want to get back to making music!
-
- 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
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
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.
Re: Develop a softsynth with LV2
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).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
- 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
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?
Re: Develop a softsynth with LV2
falkTX, can you give a short introduction to your build system. Is it just copying the plugins directory and clear all sub-directories?
Re: Develop a softsynth with LV2
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
#if DISTRHO_PLUGIN_WANT_TIMEPOS
# warning LV2 TimePos still TODO
#endif
-
- 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
This is true for .h / .hpp files as well.f00bar wrote:That is just convention, . . .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
On the road again.
Re: Develop a softsynth with LV2
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.falkTX wrote:The basic LV2 time stuff is done, but no one made a plugin that needed it until now.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
if you look at the code, the missing bits are:the other stuff on the TimePos struct is already working.Code: Select all
// TODO: // - tick // - barStartTick // - ticksPerBeat
Do you need any of those 3 in the TODO?