basic parameter support (VST)
This commit is contained in:
parent
33c2b0d78b
commit
0192351e6e
4 changed files with 292 additions and 27 deletions
2
Makefile
2
Makefile
|
@ -7,7 +7,7 @@ FULLNAME = ${DISTNAME}-${VERSION}
|
||||||
|
|
||||||
BOTH = crap_eq_const
|
BOTH = crap_eq_const
|
||||||
LADSPA_ONLY = crap_eq crap_noise
|
LADSPA_ONLY = crap_eq crap_noise
|
||||||
VST_ONLY = crap_delay_test
|
VST_ONLY = crap_eq crap_delay_test
|
||||||
LADSPA = ${BOTH:=-ladspa} ${LADSPA_ONLY:=-ladspa}
|
LADSPA = ${BOTH:=-ladspa} ${LADSPA_ONLY:=-ladspa}
|
||||||
VST = ${BOTH:=-vst} ${VST_ONLY:=-vst}
|
VST = ${BOTH:=-vst} ${VST_ONLY:=-vst}
|
||||||
PLUGINS = ${LADSPA} ${VST}
|
PLUGINS = ${LADSPA} ${VST}
|
||||||
|
|
120
crap_eq.h
Executable file
120
crap_eq.h
Executable file
|
@ -0,0 +1,120 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define BIQUAD_DOUBLE
|
||||||
|
#include "crap_util.h"
|
||||||
|
#include "param.h"
|
||||||
|
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
|
#define BANDS 4
|
||||||
|
|
||||||
|
#define ID 0x000CAFED
|
||||||
|
#define LABEL "crap_eq"
|
||||||
|
#define NAME "crap Parametric Equalizer"
|
||||||
|
#define AUTHOR "Connor Olding"
|
||||||
|
#define COPYRIGHT "MIT"
|
||||||
|
#define PARAMETERS (BANDS*3)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
biquad filters[2][BANDS];
|
||||||
|
float fs;
|
||||||
|
} personal;
|
||||||
|
|
||||||
|
static bq_t
|
||||||
|
process_one(biquad *filters, bq_t samp)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < BANDS; i++)
|
||||||
|
samp = biquad_run(&filters[i], samp);
|
||||||
|
return samp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process(personal *data,
|
||||||
|
float *in_L, float *in_R,
|
||||||
|
float *out_L, float *out_R,
|
||||||
|
unsigned long count) {
|
||||||
|
for (unsigned long pos = 0; pos < count; pos++) {
|
||||||
|
out_L[pos] = process_one(data->filters[0], in_L[pos]);
|
||||||
|
out_R[pos] = process_one(data->filters[1], in_R[pos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
process_double(personal *data,
|
||||||
|
double *in_L, double *in_R,
|
||||||
|
double *out_L, double *out_R,
|
||||||
|
unsigned long count) {
|
||||||
|
for (unsigned long pos = 0; pos < count; pos++) {
|
||||||
|
out_L[pos] = process_one(data->filters[0], in_L[pos]);
|
||||||
|
out_R[pos] = process_one(data->filters[1], in_R[pos]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resume(personal *data) {
|
||||||
|
biquad *filters = data->filters[0];
|
||||||
|
for (int i = 0; i < BANDS; i++)
|
||||||
|
biquad_init(&filters[i]);
|
||||||
|
memcpy(data->filters[1], filters, BANDS*sizeof(biquad));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pause(personal *data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
construct(personal *data, param *params) {
|
||||||
|
for (int i = 0; i < BANDS; i++) {
|
||||||
|
sprintf(params[0].name, "Band %i Frequency", i + 1);
|
||||||
|
params[0].min = 20;
|
||||||
|
params[0].max = 20000;
|
||||||
|
params[0].scale = SCALE_HZ;
|
||||||
|
params[0].def = DEFAULT_440;
|
||||||
|
param_reset(¶ms[0]);
|
||||||
|
|
||||||
|
sprintf(params[1].name, "Band %i Gain", i + 1);
|
||||||
|
params[1].min = -18;
|
||||||
|
params[1].max = 18;
|
||||||
|
params[1].scale = SCALE_DB;
|
||||||
|
params[1].def = DEFAULT_0;
|
||||||
|
param_reset(¶ms[1]);
|
||||||
|
|
||||||
|
sprintf(params[2].name, "Band %i Bandwidth", i + 1);
|
||||||
|
params[2].min = 0.0625;
|
||||||
|
params[2].max = 8;
|
||||||
|
params[2].scale = SCALE_FLOAT;
|
||||||
|
params[2].def = DEFAULT_1;
|
||||||
|
param_reset(¶ms[2]);
|
||||||
|
|
||||||
|
params += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
destruct(personal *data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust(personal *data, param *params, unsigned long fs) {
|
||||||
|
data->fs = fs;
|
||||||
|
biquad *filters = data->filters[0];
|
||||||
|
for (int i = 0; i < BANDS; i++) {
|
||||||
|
filters[i] = biquad_gen(0,
|
||||||
|
params[0].value, params[1].value, params[2].value, fs);
|
||||||
|
params += 3;
|
||||||
|
}
|
||||||
|
resume(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
adjust_one(personal *data, param *params, unsigned int index) {
|
||||||
|
float fs = data->fs;
|
||||||
|
params += index/3*3;
|
||||||
|
data->filters[0][index/3] = biquad_gen(0,
|
||||||
|
params[0].value, params[1].value, params[2].value, fs);
|
||||||
|
resume(data);
|
||||||
|
}
|
65
param.h
Executable file
65
param.h
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
#define PARAM_NAME_LEN 24
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SCALE_FLOAT,
|
||||||
|
SCALE_INT,
|
||||||
|
SCALE_TOGGLE,
|
||||||
|
SCALE_DB,
|
||||||
|
SCALE_LOG,
|
||||||
|
SCALE_HZ
|
||||||
|
} param_scale;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DEFAULT_0,
|
||||||
|
DEFAULT_1,
|
||||||
|
DEFAULT_100,
|
||||||
|
DEFAULT_440,
|
||||||
|
DEFAULT_MIN,
|
||||||
|
DEFAULT_LOW, // 25%
|
||||||
|
DEFAULT_HALF, // 50%
|
||||||
|
DEFAULT_HIGH, // 75%
|
||||||
|
DEFAULT_MAX
|
||||||
|
} param_default;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char name[PARAM_NAME_LEN + 1];
|
||||||
|
float value, min, max;
|
||||||
|
param_scale scale;
|
||||||
|
param_default def;
|
||||||
|
} param;
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
param_set(param *p, float percent)
|
||||||
|
{
|
||||||
|
if (p->scale >= SCALE_LOG)
|
||||||
|
p->value = exp(percent*(log(p->max/p->min)))*p->min;
|
||||||
|
else
|
||||||
|
p->value = percent*(p->max - p->min) + p->min;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
param_get(param *p)
|
||||||
|
{
|
||||||
|
if (p->scale >= SCALE_LOG)
|
||||||
|
return log(p->min/p->value)/log(p->min/p->max);
|
||||||
|
else
|
||||||
|
return (p->min - p->value)/(p->min - p->max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
param_reset(param *p)
|
||||||
|
{
|
||||||
|
switch (p->def) {
|
||||||
|
case DEFAULT_0: p->value = 0; break;
|
||||||
|
case DEFAULT_1: p->value = 1; break;
|
||||||
|
case DEFAULT_100: p->value = 100; break;
|
||||||
|
case DEFAULT_440: p->value = 440; break;
|
||||||
|
case DEFAULT_MIN: p->value = p->min; break;
|
||||||
|
case DEFAULT_LOW: param_set(p, 0.25); break;
|
||||||
|
case DEFAULT_HALF: param_set(p, 0.5); break;
|
||||||
|
case DEFAULT_HIGH: param_set(p, 0.75); break;
|
||||||
|
case DEFAULT_MAX: p->value = p->max; break;
|
||||||
|
}
|
||||||
|
}
|
132
template-vst.cpp
132
template-vst.cpp
|
@ -1,8 +1,12 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include "public.sdk/source/vst2.x/audioeffectx.h"
|
#include "public.sdk/source/vst2.x/audioeffectx.h"
|
||||||
//#include "vstparam.h"
|
|
||||||
|
|
||||||
//#INCLUDE
|
//#INCLUDE
|
||||||
|
|
||||||
|
// VST 2.4 by standard only holds 8 (+ 1 null) length strings,
|
||||||
|
// but this is never the case in practice. I've seen up to 24.
|
||||||
|
#define MAX_PARAM_LEN 24
|
||||||
|
|
||||||
class plugin : public AudioEffectX
|
class plugin : public AudioEffectX
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -16,23 +20,23 @@ public:
|
||||||
|
|
||||||
bool setProcessPrecision(VstInt32 precision);
|
bool setProcessPrecision(VstInt32 precision);
|
||||||
|
|
||||||
/*
|
|
||||||
void setParameter(VstInt32, float);
|
|
||||||
float getParameter(VstInt32);
|
|
||||||
void getParameterLabel(VstInt32, char *);
|
|
||||||
void getParameterDisplay(VstInt32, char *);
|
|
||||||
void getParameterName(VstInt32, char *);
|
|
||||||
*/
|
|
||||||
|
|
||||||
void setSampleRate(float);
|
void setSampleRate(float);
|
||||||
bool getEffectName(char *);
|
bool getEffectName(char *);
|
||||||
bool getVendorString(char *);
|
bool getVendorString(char *);
|
||||||
bool getProductString(char *);
|
bool getProductString(char *);
|
||||||
//VstInt32 getVendorVersion();
|
//VstInt32 getVendorVersion();
|
||||||
|
|
||||||
|
#if (PARAMETERS > 0)
|
||||||
|
void setParameter(VstInt32, float);
|
||||||
|
float getParameter(VstInt32);
|
||||||
|
void getParameterName(VstInt32, char *); // eg. Gain
|
||||||
|
void getParameterDisplay(VstInt32, char *); // eg. -3.3
|
||||||
|
void getParameterLabel(VstInt32, char *); // eg. dB
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if (PARAMETERS > 0)
|
#if (PARAMETERS > 0)
|
||||||
VstParam *m_params[PARAMETERS];
|
param params[PARAMETERS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
personal data;
|
personal data;
|
||||||
|
@ -46,20 +50,20 @@ createEffectInstance(audioMasterCallback audioMaster) {
|
||||||
plugin::plugin(audioMasterCallback audioMaster)
|
plugin::plugin(audioMasterCallback audioMaster)
|
||||||
: AudioEffectX(audioMaster, 1, PARAMETERS)
|
: AudioEffectX(audioMaster, 1, PARAMETERS)
|
||||||
{
|
{
|
||||||
//#VST_PARAMS
|
|
||||||
//m_params[n] = new VstParam("Input", "dB", -12.0, 12.0, 0.0, NULL, NULL, 1, NULL);
|
|
||||||
setNumInputs(2);
|
setNumInputs(2);
|
||||||
setNumOutputs(2);
|
setNumOutputs(2);
|
||||||
setUniqueID(ID);
|
setUniqueID(ID);
|
||||||
canProcessReplacing();
|
canProcessReplacing();
|
||||||
|
#if (PARAMETERS > 0)
|
||||||
|
::construct(&data, params);
|
||||||
|
#else
|
||||||
::construct(&data);
|
::construct(&data);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin::~plugin()
|
plugin::~plugin()
|
||||||
{
|
{
|
||||||
::destruct(&data);
|
::destruct(&data);
|
||||||
//for (int i = 0; i < PARAMETERS; i++)
|
|
||||||
// delete m_params[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -92,18 +96,17 @@ plugin::processDoubleReplacing(double **inputs, double **outputs, VstInt32 count
|
||||||
|
|
||||||
bool
|
bool
|
||||||
plugin::setProcessPrecision(VstInt32 precision) {
|
plugin::setProcessPrecision(VstInt32 precision) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
parameter funcs go here
|
|
||||||
if (index >= PARAMETERS) return;
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
plugin::setSampleRate(float fs) {
|
plugin::setSampleRate(float fs) {
|
||||||
AudioEffectX::setSampleRate(fs);
|
AudioEffectX::setSampleRate(fs);
|
||||||
|
#if (PARAMETERS > 0)
|
||||||
|
::adjust(&data, params, (unsigned long) fs);
|
||||||
|
#else
|
||||||
::adjust(&data, (unsigned long) fs);
|
::adjust(&data, (unsigned long) fs);
|
||||||
|
#endif
|
||||||
#ifdef DELAY
|
#ifdef DELAY
|
||||||
setInitialDelay(global_delay);
|
setInitialDelay(global_delay);
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,20 +114,97 @@ plugin::setSampleRate(float fs) {
|
||||||
|
|
||||||
bool
|
bool
|
||||||
plugin::getEffectName(char *name) {
|
plugin::getEffectName(char *name) {
|
||||||
vst_strncpy(name, LABEL, kVstMaxEffectNameLen);
|
vst_strncpy(name, LABEL, kVstMaxEffectNameLen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
plugin::getProductString(char *text)
|
plugin::getProductString(char *text)
|
||||||
{
|
{
|
||||||
vst_strncpy(text, NAME, kVstMaxProductStrLen);
|
vst_strncpy(text, NAME, kVstMaxProductStrLen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
plugin::getVendorString(char *text)
|
plugin::getVendorString(char *text)
|
||||||
{
|
{
|
||||||
vst_strncpy(text, AUTHOR, kVstMaxVendorStrLen);
|
vst_strncpy(text, AUTHOR, kVstMaxVendorStrLen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (PARAMETERS > 0)
|
||||||
|
void
|
||||||
|
plugin::setParameter(VstInt32 index, float value)
|
||||||
|
{
|
||||||
|
if (index >= PARAMETERS) return;
|
||||||
|
param_set(¶ms[index], value);
|
||||||
|
::adjust_one(&data, params, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
plugin::getParameter(VstInt32 index)
|
||||||
|
{
|
||||||
|
if (index >= PARAMETERS) return 0;
|
||||||
|
return param_get(¶ms[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plugin::getParameterName(VstInt32 index, char *text)
|
||||||
|
{
|
||||||
|
if (index >= PARAMETERS) return;
|
||||||
|
vst_strncpy(text, params[index].name, MAX_PARAM_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plugin::getParameterDisplay(VstInt32 index, char *text)
|
||||||
|
{
|
||||||
|
if (index >= PARAMETERS) return;
|
||||||
|
|
||||||
|
param *p = ¶ms[index];
|
||||||
|
char display[MAX_PARAM_LEN];
|
||||||
|
|
||||||
|
switch (p->scale) {
|
||||||
|
case SCALE_FLOAT:
|
||||||
|
case SCALE_LOG:
|
||||||
|
case SCALE_HZ:
|
||||||
|
case SCALE_DB:
|
||||||
|
sprintf(display, "%0.2f", p->value);
|
||||||
|
break;
|
||||||
|
case SCALE_INT:
|
||||||
|
sprintf(display, "%i", (int) p->value);
|
||||||
|
break;
|
||||||
|
case SCALE_TOGGLE:
|
||||||
|
sprintf(display, (param_get(p) < 0.5) ? "off" : "on");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(display, "error");
|
||||||
|
}
|
||||||
|
|
||||||
|
vst_strncpy(text, display, MAX_PARAM_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
plugin::getParameterLabel(VstInt32 index, char *text)
|
||||||
|
{
|
||||||
|
if (index >= PARAMETERS) return;
|
||||||
|
|
||||||
|
param *p = ¶ms[index];
|
||||||
|
char display[MAX_PARAM_LEN];
|
||||||
|
|
||||||
|
switch (p->scale) {
|
||||||
|
case SCALE_HZ:
|
||||||
|
sprintf(display, "Hz");
|
||||||
|
break;
|
||||||
|
case SCALE_DB:
|
||||||
|
sprintf(display, "dB");
|
||||||
|
break;
|
||||||
|
case SCALE_FLOAT:
|
||||||
|
case SCALE_INT:
|
||||||
|
case SCALE_TOGGLE:
|
||||||
|
case SCALE_LOG:
|
||||||
|
display[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vst_strncpy(text, display, MAX_PARAM_LEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue