
32 changed files with 26 additions and 308 deletions
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
# See manifest.ttl.in in the eg-amp.lv2 example for an explanation of this file |
||||
|
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> . |
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . |
||||
|
||||
<http://lv2plug.in/plugins/eg-synth> |
||||
a lv2:Plugin ; |
||||
lv2:binary <synth@LIB_EXT@> ; |
||||
rdfs:seeAlso <synth.ttl> . |
@ -1,171 +0,0 @@
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
Copyright 2012 Harry van Haaren <harryhaaren@gmail.com> |
||||
Copyright 2012 David Robillard <d@drobilla.net> |
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any |
||||
purpose with or without fee is hereby granted, provided that the above |
||||
copyright notice and this permission notice appear in all copies. |
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
/**
|
||||
@file synth.c Implementation of the LV2 Sin Synth example plugin. |
||||
|
||||
This is a simple LV2 synthesis plugin that demonstrates how to receive MIDI |
||||
events and render audio in response to them. |
||||
*/ |
||||
|
||||
#include <math.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "lv2/lv2plug.in/ns/lv2core/lv2.h" |
||||
|
||||
#define SYNTH_URI "http://lv2plug.in/plugins/eg-synth"
|
||||
|
||||
/** Port indices. */ |
||||
typedef enum { |
||||
SYNTH_FREQ = 0, |
||||
SYNTH_OUTPUT, |
||||
} PortIndex; |
||||
|
||||
/** Plugin instance. */ |
||||
typedef struct { |
||||
// Sample rate, necessary to generate sin wave in run()
|
||||
double sample_rate; |
||||
|
||||
// Current wave phase
|
||||
float phase; |
||||
|
||||
// Port buffers
|
||||
const float* freq; |
||||
float* output; |
||||
} Synth; |
||||
|
||||
/** Create a new plugin instance. */ |
||||
static LV2_Handle |
||||
instantiate(const LV2_Descriptor* descriptor, |
||||
double rate, |
||||
const char* bundle_path, |
||||
const LV2_Feature* const* features) |
||||
{ |
||||
Synth* self = (Synth*)malloc(sizeof(Synth)); |
||||
if (self) { |
||||
// Store the sample rate so it is available in run()
|
||||
self->sample_rate = rate; |
||||
} |
||||
return (LV2_Handle)self; |
||||
} |
||||
|
||||
/** Connect a port to a buffer (audio thread, must be RT safe). */ |
||||
static void |
||||
connect_port(LV2_Handle instance, |
||||
uint32_t port, |
||||
void* data) |
||||
{ |
||||
Synth* self = (Synth*)instance; |
||||
|
||||
switch ((PortIndex)port) { |
||||
case SYNTH_FREQ: |
||||
self->freq = (const float*)data; |
||||
break; |
||||
case SYNTH_OUTPUT: |
||||
self->output = (float*)data; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** Initialise and prepare the plugin instance for running. */ |
||||
static void |
||||
activate(LV2_Handle instance) |
||||
{ |
||||
Synth* self = (Synth*)instance; |
||||
|
||||
// Initialize phase so we start at the beginning of the wave
|
||||
self->phase = 0.0f; |
||||
} |
||||
|
||||
/** Process a block of audio (audio thread, must be RT safe). */ |
||||
static void |
||||
run(LV2_Handle instance, uint32_t n_samples) |
||||
{ |
||||
Synth* self = (Synth*)instance; |
||||
|
||||
const float PI = 3.1415; |
||||
const float volume = 0.3; |
||||
const float freq = *(self->freq); |
||||
float* const output = self->output; |
||||
|
||||
float samples_per_cycle = self->sample_rate / freq; |
||||
|
||||
/* Calculate the phase offset per sample. Phase ranges from 0..1, so
|
||||
phase_increment is a floating point number such that we get "freq" |
||||
number of cycles in "sample_rate" amount of samples. */ |
||||
float phase_increment = (1.f / samples_per_cycle); |
||||
|
||||
for (uint32_t pos = 0; pos < n_samples; pos++) { |
||||
/* Calculate the next sample. Phase ranges from 0..1, but sin()
|
||||
expects its input in radians, so we multiply by 2 PI to convert it. |
||||
We also multiply by volume so it's not extremely loud. */ |
||||
output[pos] = sin(self->phase * 2 * PI) * volume; |
||||
|
||||
/* Increment the phase so we generate the next sample */ |
||||
self->phase += phase_increment; |
||||
if (self->phase > 1.0f) { |
||||
self->phase = 0.0f; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** Finish running (counterpart to activate()). */ |
||||
static void |
||||
deactivate(LV2_Handle instance) |
||||
{ |
||||
/* Nothing to do here in this trivial mostly stateless plugin. */ |
||||
} |
||||
|
||||
/** Destroy a plugin instance (counterpart to instantiate()). */ |
||||
static void |
||||
cleanup(LV2_Handle instance) |
||||
{ |
||||
free(instance); |
||||
} |
||||
|
||||
/** Return extension data provided by the plugin. */ |
||||
static const void* |
||||
extension_data(const char* uri) |
||||
{ |
||||
return NULL; /* This plugin has no extension data. */ |
||||
} |
||||
|
||||
/** The LV2_Descriptor for this plugin. */ |
||||
static const LV2_Descriptor descriptor = { |
||||
SYNTH_URI, |
||||
instantiate, |
||||
connect_port, |
||||
activate, |
||||
run, |
||||
deactivate, |
||||
cleanup, |
||||
extension_data |
||||
}; |
||||
|
||||
/** Entry point, the host will call this function to access descriptors. */ |
||||
LV2_SYMBOL_EXPORT |
||||
const LV2_Descriptor* |
||||
lv2_descriptor(uint32_t index) |
||||
{ |
||||
switch (index) { |
||||
case 0: |
||||
return &descriptor; |
||||
default: |
||||
return NULL; |
||||
} |
||||
} |
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
# LV2 Sinewave synth plugin |
||||
# Copyright 2012 Harry van Haaren <harryhaaren@gmail.com> |
||||
# |
||||
# Permission to use, copy, modify, and/or distribute this software for any |
||||
# purpose with or without fee is hereby granted, provided that the above |
||||
# copyright notice and this permission notice appear in all copies. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
||||
|
||||
@prefix doap: <http://usefulinc.com/ns/doap#> . |
||||
@prefix foaf: <http://xmlns.com/foaf/0.1/> . |
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> . |
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . |
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . |
||||
|
||||
<http://lv2plug.in/plugins/eg-synth> |
||||
a lv2:Plugin , |
||||
lv2:InstrumentPlugin ; |
||||
doap:name "Example Synthesizer" ; |
||||
doap:license <http://opensource.org/licenses/isc> ; |
||||
lv2:project <http://lv2plug.in/ns/lv2> ; |
||||
lv2:optionalFeature lv2:hardRTCapable ; |
||||
lv2:port [ |
||||
a lv2:InputPort , |
||||
lv2:ControlPort ; |
||||
lv2:index 0 ; |
||||
lv2:symbol "frequency" ; |
||||
lv2:name "Frequency" ; |
||||
lv2:default 440.0 ; |
||||
lv2:minimum 40.0 ; |
||||
lv2:maximum 880.0 |
||||
] , [ |
||||
a lv2:AudioPort , |
||||
lv2:OutputPort ; |
||||
lv2:index 1 ; |
||||
lv2:symbol "out" ; |
||||
lv2:name "Out" |
||||
] . |
@ -1,64 +0,0 @@
@@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env python |
||||
from waflib.extras import autowaf as autowaf |
||||
import re |
||||
|
||||
# Variables for 'waf dist' |
||||
APPNAME = 'eg-synth.lv2' |
||||
VERSION = '1.0.0' |
||||
|
||||
# Mandatory variables |
||||
top = '.' |
||||
out = 'build' |
||||
|
||||
def options(opt): |
||||
opt.load('compiler_c') |
||||
autowaf.set_options(opt) |
||||
|
||||
def configure(conf): |
||||
conf.load('compiler_c') |
||||
autowaf.configure(conf) |
||||
autowaf.set_c99_mode(conf) |
||||
autowaf.display_header('Synth Configuration') |
||||
|
||||
if not autowaf.is_child(): |
||||
autowaf.check_pkg(conf, 'lv2', uselib_store='LV2') |
||||
|
||||
autowaf.display_msg(conf, 'LV2 bundle directory', conf.env.LV2DIR) |
||||
print('') |
||||
|
||||
def build(bld): |
||||
bundle = APPNAME |
||||
|
||||
# Make a pattern for shared objects without the 'lib' prefix |
||||
module_pat = re.sub('^lib', '', bld.env.cshlib_PATTERN) |
||||
module_ext = module_pat[module_pat.rfind('.'):] |
||||
|
||||
# Build manifest.ttl by substitution (for portable lib extension) |
||||
bld(features = 'subst', |
||||
source = 'manifest.ttl.in', |
||||
target = '%s/%s' % (bundle, 'manifest.ttl'), |
||||
install_path = '${LV2DIR}/%s' % bundle, |
||||
LIB_EXT = module_ext) |
||||
|
||||
# Copy other data files to build bundle (build/eg-amp.lv2) |
||||
for i in ['synth.ttl']: |
||||
bld(features = 'subst', |
||||
is_copy = True, |
||||
source = i, |
||||
target = '%s/%s' % (bundle, i), |
||||
install_path = '${LV2DIR}/%s' % bundle) |
||||
|
||||
# Use LV2 headers from parent directory if building as a sub-project |
||||
includes = None |
||||
if autowaf.is_child: |
||||
includes = '../..' |
||||
|
||||
# Build plugin library |
||||
obj = bld(features = 'c cshlib', |
||||
source = 'synth.c', |
||||
name = 'synth', |
||||
target = '%s/synth' % bundle, |
||||
install_path = '${LV2DIR}/%s' % bundle, |
||||
uselib = 'LV2', |
||||
includes = includes) |
||||
obj.env.cshlib_PATTERN = module_pat |
@ -1,8 +1,17 @@
@@ -1,8 +1,17 @@
|
||||
# The full description of the plugin is in this file, which is linked to from |
||||
# `manifest.ttl`. This is done so the host only needs to scan the relatively |
||||
# small `manifest.ttl` files to quickly discover all plugins. |
||||
|
||||
@prefix doap: <http://usefulinc.com/ns/doap#> . |
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> . |
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . |
||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> . |
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . |
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . |
||||
|
||||
# First the type of the plugin is described. All plugins must explicitly list |
||||
# `lv2:Plugin` as a type. A more specific type should also be given, where |
||||
# applicable, so hosts can present a nicer UI for loading plugins. Note that |
||||
# this URI is the identifier of the plugin, so if it does not match the one in |
||||
# `manifest.ttl`, the host will not discover the plugin data at all. |
||||
<http://lv2plug.in/plugins/eg-amp> |
||||
a lv2:Plugin , |
||||
lv2:AmplifierPlugin ; |
Loading…
Reference in new issue