differentiate and fix c++ fx and synth, beginning of synthpp_simple

This commit is contained in:
Stefano D'Angelo 2024-02-09 17:21:29 +01:00
parent a9a690bc69
commit 404530cbbe
19 changed files with 444 additions and 10 deletions

View File

@ -12,7 +12,7 @@ void impl_set_sample_rate(impl handle, float sample_rate);
void impl_reset(impl handle);
void impl_set_parameter(impl handle, size_t index, float value);
float impl_get_parameter(impl handle, size_t index);
void impl_process(impl handle, const float **inputs, float **outputs, size_t n_samples);
void impl_process(impl handle, const float ** inputs, float ** outputs, size_t n_samples);
#ifdef __cplusplus
}

View File

@ -0,0 +1,21 @@
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void * impl;
impl impl_new(void);
void impl_free(impl handle);
void impl_set_sample_rate(impl handle, float sample_rate);
void impl_reset(impl handle);
void impl_set_parameter(impl handle, size_t index, float value);
float impl_get_parameter(impl handle, size_t index);
void impl_process(impl handle, const float ** inputs, float ** outputs, size_t n_samples);
void impl_midi_msg_in(impl handle, size_t index, const uint8_t * data);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,48 @@
#include "common.h"
#include "impl.h"
typedef struct plugin {
impl handle;
} plugin;
static void plugin_init(plugin *instance) {
instance->handle = impl_new();
}
static void plugin_fini(plugin *instance) {
impl_free(instance->handle);
}
static void plugin_set_sample_rate(plugin *instance, float sample_rate) {
impl_set_sample_rate(instance->handle, sample_rate);
}
static size_t plugin_mem_req(plugin *instance) {
(void)instance;
return 0;
}
static void plugin_mem_set(plugin *instance, void *mem) {
(void)instance;
(void)mem;
}
static void plugin_reset(plugin *instance) {
impl_reset(instance->handle);
}
static void plugin_set_parameter(plugin *instance, size_t index, float value) {
impl_set_parameter(instance->handle, index, value);
}
static float plugin_get_parameter(plugin *instance, size_t index) {
return impl_get_parameter(instance->handle, index);
}
static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) {
impl_process(instance->handle, inputs, outputs, n_samples);
}
static void plugin_midi_msg_in(plugin *instance, size_t index, const uint8_t *data) {
impl_midi_msg_in(instance->handle, index, data);
}

View File

@ -7,8 +7,8 @@
],
"deploymentTarget": 16.6,
"commonDir": "../../common/ios",
"pluginDir": "../../common/src/cxx",
"cSrcs": "../../common/src/cxx/impl.h",
"pluginDir": "../../common/src/cxx-fx",
"cSrcs": "../../common/src/cxx-fx/impl.h",
"cxxSrcs": "../src/impl.cpp"
}
}

View File

@ -0,0 +1,14 @@
{
"ios_make": {
"headerSearchPaths": [
"../../../../../../miniaudio",
"../../../../common/src",
"../../../../../include"
],
"deploymentTarget": 16.6,
"commonDir": "../../common/ios",
"pluginDir": "../../common/src/cxx-synth",
"cSrcs": "../../common/src/cxx-synth/impl.h",
"cxxSrcs": "../src/impl.cpp"
}
}

View File

@ -1,8 +1,8 @@
{
"make": {
"cxxSrcs": "../src/impl.cpp",
"cflags": "-I../../../include -I../../common/src -I../../common/src/cxx",
"cxxflags": "-I../../../include -I../../common/src -I../../common/src/cxx -std=c++11",
"pluginDir": "../src"
"cflags": "-I../../../include -I../../common/src -I../../common/src/cxx-fx",
"cxxflags": "-I../../../include -I../../common/src -I../../common/src/cxx-fx -std=c++11",
"pluginDir": "../../common/src/cxx-fx"
}
}

View File

@ -0,0 +1,8 @@
{
"make": {
"cxxSrcs": "../src/impl.cpp",
"cflags": "-I../../../include -I../../common/src -I../../common/src/cxx-synth",
"cxxflags": "-I../../../include -I../../common/src -I../../common/src/cxx-synth -std=c++11",
"pluginDir": "../../common/src/cxx-synth"
}
}

View File

@ -131,7 +131,7 @@ static void plugin_process(plugin *instance, const float **inputs, float **outpu
if (instance->note >= 0)
bw_phase_gen_set_frequency(&instance->phase_gen_coeffs,
instance->master_tune * bw_pow2f(8.333333333333333e-2f * ((instance->note - 69))));
instance->master_tune * bw_pow2f(8.333333333333333e-2f * (instance->note - 69)));
for (size_t i = 0; i < n_samples; i += BUFFER_SIZE) {
float *out = outputs[0] + i;

View File

@ -0,0 +1,5 @@
{
"android": {
"javaPackageName": "com.orastron.bw_example_synthpp_simple"
}
}

View File

@ -0,0 +1,6 @@
{
"cmd": {
"busIds": [ "midi_in", "output" ],
"parameterIds": [ "volume", "master_tune", "portamento", "pulse_width", "cutoff", "resonance", "attack", "decay", "sustain", "release", "level" ]
}
}

View File

@ -0,0 +1,6 @@
{
"daisy_seed": {
"parameterPins": [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22 ],
"midiCCMaps": [ 7, 3, 5, 28, 74, 71, 73, 109, 110, 72, -1 ]
}
}

View File

@ -0,0 +1,160 @@
#define IMPL_MIDI
#include "impl.h"
#include "common.h"
#include <bw_phase_gen.h>
#include <bw_osc_pulse.h>
#include <bw_osc_filt.h>
#include <bw_svf.h>
#include <bw_env_gen.h>
#include <bw_gain.h>
#include <bw_ppm.h>
#include <bw_buf.h>
#define BUFFER_SIZE 128
using namespace Brickworks;
class Engine {
public:
PhaseGen<1> phaseGen;
OscPulse<1> oscPulse;
OscFilt<1> oscFilt;
SVF<1> svf;
EnvGen<1> envGen;
Gain<1> gain;
PPM<1> ppm;
float masterTune;
int note;
float buf[BUFFER_SIZE];
};
extern "C" {
impl impl_new(void) {
Engine *instance = new Engine();
instance->oscPulse.setAntialiasing(true);
instance->masterTune = 440.f;
return reinterpret_cast<impl>(instance);
}
void impl_free(impl handle) {
Engine *instance = reinterpret_cast<Engine *>(handle);
delete instance;
}
void impl_set_sample_rate(impl handle, float sample_rate) {
Engine *instance = reinterpret_cast<Engine *>(handle);
instance->phaseGen.setSampleRate(sample_rate);
instance->oscPulse.setSampleRate(sample_rate);
instance->svf.setSampleRate(sample_rate);
instance->envGen.setSampleRate(sample_rate);
instance->gain.setSampleRate(sample_rate);
instance->ppm.setSampleRate(sample_rate);
}
void impl_reset(impl handle) {
Engine *instance = reinterpret_cast<Engine *>(handle);
instance->phaseGen.reset();
instance->oscPulse.reset();
instance->oscFilt.reset();
instance->svf.reset();
instance->envGen.reset();
instance->gain.reset();
instance->ppm.reset();
instance->note = -1;
}
void impl_set_parameter(impl handle, size_t index, float value) {
Engine *instance = reinterpret_cast<Engine *>(handle);
switch (index) {
case 0:
{
float v = 0.01f * value;
instance->gain.setGainLin(v * v * v);
}
break;
case 1:
instance->masterTune = value;
break;
case 2:
// using portamento time 0% -> 90%: tau = portamento time / log(10)
instance->phaseGen.setPortamentoTau(0.4342944819032517f * value);
break;
case 3:
instance->oscPulse.setPulseWidth(0.01f * value);
break;
case 4:
instance->svf.setCutoff(value);
break;
case 5:
instance->svf.setQ(0.5f + (9.5f * 0.01f) * value);
break;
case 6:
instance->envGen.setAttack(0.001f * value);
break;
case 7:
instance->envGen.setDecay(0.001f * value);
break;
case 8:
instance->envGen.setSustain(0.01f * value);
break;
case 9:
instance->envGen.setRelease(0.001f * value);
break;
}
}
float impl_get_parameter(impl handle, size_t index) {
(void)index;
Engine *instance = reinterpret_cast<Engine *>(handle);
return bw_clipf(instance->ppm.getYZ1(0), -60.f, 0.f);
}
void impl_process(impl handle, const float **inputs, float **outputs, size_t n_samples) {
(void)inputs;
Engine *instance = reinterpret_cast<Engine *>(handle);
if (instance->note >= 0)
instance->phaseGen.setFrequency(instance->masterTune * bw_pow2f(8.333333333333333e-2f * (instance->note - 69)));
for (size_t i = 0; i < n_samples; i += BUFFER_SIZE) {
float *out = outputs[0] + i;
int n = bw_minf(n_samples - i, BUFFER_SIZE);
#ifdef WASM
#else
instance->phaseGen.process({nullptr}, {out}, {instance->buf}, n);
instance->oscPulse.process({out}, {instance->buf}, {out}, n);
instance->oscFilt.process({out}, {out}, n);
instance->svf.process({out}, {out}, {nullptr}, {nullptr}, n);
instance->envGen.process({instance->note >= 0}, {instance->buf}, n);
bufMul<1>({out}, {instance->buf}, {out}, n);
instance->gain.process({out}, {out}, n);
instance->ppm.process({out}, {nullptr}, n);
#endif
}
}
void impl_midi_msg_in(impl handle, size_t index, const uint8_t * data) {
(void)index;
Engine *instance = reinterpret_cast<Engine *>(handle);
switch (data[0] & 0xf0) {
case 0x90: // note on
if (data[2] == 0) { // no, note off actually
if (data[1] == instance->note)
instance->note = -1;
} else
instance->note = data[1];
break;
case 0x80: // note off
if (data[1] == instance->note)
instance->note = -1;
break;
}
}
}

View File

@ -0,0 +1,5 @@
{
"ios": {
"productBundleIdentifier": "com.orastron.bw_example_synthpp_simple"
}
}

View File

@ -0,0 +1,12 @@
{
"lv2": {
"prefixes": {
"bw_examples": "https://www.orastron.com/brickworks/examples/"
},
"uri": "@bw_examples:synthpp_simple",
"types": [ "@lv2:InstrumentPlugin" ],
"version": "1.0",
"busSymbols": [ "midi_in", "output" ],
"parameterSymbols": [ "volume", "master_tune", "portamento", "pulse_width", "cutoff", "resonance", "attack", "decay", "sustain", "release", "level" ]
}
}

View File

@ -0,0 +1,135 @@
{
"product": {
"name": "Brickworks simple synth example (C++)",
"version": "1.1.0",
"buildVersion": "1",
"bundleName": "bw_example_synthpp_simple",
"buses": [
{
"type": "midi",
"direction": "input",
"name": "MIDI input",
"shortName": "MIDI input"
},
{
"type": "audio",
"direction": "output",
"channels": "mono",
"name": "Output",
"shortName": "Output"
}
],
"parameters": [
{
"name": "Volume",
"shortName": "Volume",
"direction": "input",
"defaultValue": 50.0,
"minimum": 0.0,
"maximum": 100.0,
"unit": "pc",
"map": "linear"
},
{
"name": "Master tune",
"shortName": "Master tune",
"direction": "input",
"defaultValue": 440.0,
"minimum": 415.304697579945,
"maximum": 466.1637615180899,
"unit": "hz",
"map": "logarithmic"
},
{
"name": "Portamento",
"shortName": "Portamento",
"direction": "input",
"defaultValue": 0.0,
"minimum": 0.0,
"maximum": 1.0,
"unit": "s",
"map": "linear"
},
{
"name": "Pulse width",
"shortName": "Pulse width",
"direction": "input",
"defaultValue": 50.0,
"minimum": 0.0,
"maximum": 100.0,
"unit": "pc",
"map": "linear"
},
{
"name": "Cutoff",
"shortName": "Cutoff",
"direction": "input",
"defaultValue": 20e3,
"minimum": 20.0,
"maximum": 20e3,
"unit": "hz",
"map": "logarithmic"
},
{
"name": "Resonance",
"shortName": "Resonance",
"direction": "input",
"defaultValue": 0.0,
"minimum": 0.0,
"maximum": 100.0,
"unit": "pc",
"map": "linear"
},
{
"name": "Attack",
"shortName": "Attack",
"direction": "input",
"defaultValue": 2.0,
"minimum": 2.0,
"maximum": 1000.0,
"unit": "ms",
"map": "linear"
},
{
"name": "Decay",
"shortName": "Decay",
"direction": "input",
"defaultValue": 2.0,
"minimum": 2.0,
"maximum": 1000.0,
"unit": "ms",
"map": "linear"
},
{
"name": "Sustain",
"shortName": "Sustain",
"direction": "input",
"defaultValue": 100.0,
"minimum": 0.0,
"maximum": 100.0,
"unit": "pc",
"map": "linear"
},
{
"name": "Release",
"shortName": "Release",
"direction": "input",
"defaultValue": 2.0,
"minimum": 2.0,
"maximum": 1000.0,
"unit": "ms",
"map": "linear"
},
{
"name": "Level",
"shortName": "Level",
"direction": "output",
"defaultValue": -60.0,
"minimum": -60.0,
"maximum": 0.0,
"unit": "db",
"map": "linear"
}
]
}
}

View File

@ -0,0 +1,11 @@
{
"vst3": {
"plugin": {
"cid": "5008d6f47b104d368163d0a04a599a52"
},
"controller": {
"cid": "e6967755daf848908858da74887ca242"
},
"subCategory": "Instrument|Synth"
}
}

View File

@ -4,7 +4,7 @@ echo Removing common files
rm -fr common/cmd common/web common/daisy-seed common/lv2 common/vst3 common/android common/ios
dirs="fx_ap1 fx_ap2 fx_balance fx_bitcrush fx_cab fx_comp synth_simple fxpp_ap1 fxpp_ap2 fxpp_balance fxpp_bitcrush fxpp_cab fxpp_comp"
dirs="fx_ap1 fx_ap2 fx_balance fx_bitcrush fx_cab fx_comp synth_simple fxpp_ap1 fxpp_ap2 fxpp_balance fxpp_bitcrush fxpp_cab fxpp_comp synthpp_simple"
for d in $dirs; do
echo Removing data files for $d

View File

@ -26,14 +26,17 @@ cd common && $TIBIA_DIR/tibia --common $TIBIA_DIR/templates/android-make android
cd common && $TIBIA_DIR/tibia --common $TIBIA_DIR/templates/ios ios && cd ..
cd common && $TIBIA_DIR/tibia --common $TIBIA_DIR/templates/ios-make ios && cd ..
dirs="fx_ap1 fx_ap2 fx_balance fx_bitcrush fx_cab fx_comp synth_simple fxpp_ap1 fxpp_ap2 fxpp_balance fxpp_bitcrush fxpp_cab fxpp_comp"
dirs="fx_ap1 fx_ap2 fx_balance fx_bitcrush fx_cab fx_comp synth_simple fxpp_ap1 fxpp_ap2 fxpp_balance fxpp_bitcrush fxpp_cab fxpp_comp synthpp_simple"
for d in $dirs; do
echo Generating data files for $d
case $d in
fxpp*)
make_json=make-cxx.json
make_json=make-cxx-fx.json
;;
synthpp*)
make_json=make-cxx-synth.json
;;
*)
make_json=make.json