basic parameter support (VST)

This commit is contained in:
Connor Olding 2014-01-29 17:55:11 -08:00
parent 33c2b0d78b
commit 0192351e6e
4 changed files with 292 additions and 27 deletions

View file

@ -7,7 +7,7 @@ FULLNAME = ${DISTNAME}-${VERSION}
BOTH = crap_eq_const
LADSPA_ONLY = crap_eq crap_noise
VST_ONLY = crap_delay_test
VST_ONLY = crap_eq crap_delay_test
LADSPA = ${BOTH:=-ladspa} ${LADSPA_ONLY:=-ladspa}
VST = ${BOTH:=-vst} ${VST_ONLY:=-vst}
PLUGINS = ${LADSPA} ${VST}

120
crap_eq.h Executable file
View 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(&params[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(&params[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(&params[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
View 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;
}
}

View file

@ -1,8 +1,12 @@
#include <stdio.h>
#include "public.sdk/source/vst2.x/audioeffectx.h"
//#include "vstparam.h"
//#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
{
public:
@ -16,23 +20,23 @@ public:
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);
bool getEffectName(char *);
bool getVendorString(char *);
bool getProductString(char *);
//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:
#if (PARAMETERS > 0)
VstParam *m_params[PARAMETERS];
param params[PARAMETERS];
#endif
personal data;
@ -46,20 +50,20 @@ createEffectInstance(audioMasterCallback audioMaster) {
plugin::plugin(audioMasterCallback audioMaster)
: 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);
setNumOutputs(2);
setUniqueID(ID);
canProcessReplacing();
#if (PARAMETERS > 0)
::construct(&data, params);
#else
::construct(&data);
#endif
}
plugin::~plugin()
{
::destruct(&data);
//for (int i = 0; i < PARAMETERS; i++)
// delete m_params[i];
}
void
@ -92,18 +96,17 @@ plugin::processDoubleReplacing(double **inputs, double **outputs, VstInt32 count
bool
plugin::setProcessPrecision(VstInt32 precision) {
return true;
return true;
}
/*
parameter funcs go here
if (index >= PARAMETERS) return;
*/
void
plugin::setSampleRate(float fs) {
AudioEffectX::setSampleRate(fs);
#if (PARAMETERS > 0)
::adjust(&data, params, (unsigned long) fs);
#else
::adjust(&data, (unsigned long) fs);
#endif
#ifdef DELAY
setInitialDelay(global_delay);
#endif
@ -111,20 +114,97 @@ plugin::setSampleRate(float fs) {
bool
plugin::getEffectName(char *name) {
vst_strncpy(name, LABEL, kVstMaxEffectNameLen);
return true;
vst_strncpy(name, LABEL, kVstMaxEffectNameLen);
return true;
}
bool
plugin::getProductString(char *text)
{
vst_strncpy(text, NAME, kVstMaxProductStrLen);
return true;
vst_strncpy(text, NAME, kVstMaxProductStrLen);
return true;
}
bool
plugin::getVendorString(char *text)
{
vst_strncpy(text, AUTHOR, kVstMaxVendorStrLen);
return true;
vst_strncpy(text, AUTHOR, kVstMaxVendorStrLen);
return true;
}
#if (PARAMETERS > 0)
void
plugin::setParameter(VstInt32 index, float value)
{
if (index >= PARAMETERS) return;
param_set(&params[index], value);
::adjust_one(&data, params, index);
}
float
plugin::getParameter(VstInt32 index)
{
if (index >= PARAMETERS) return 0;
return param_get(&params[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 = &params[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 = &params[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