first commit

This commit is contained in:
2025-10-25 14:39:11 +02:00
commit cba857af61
21 changed files with 1128 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
[submodule "submodules/make"]
path = submodules/make
url = http://192.168.22.90:3001/jayfield/make.git
View File
+11
View File
@@ -0,0 +1,11 @@
{
"C_Cpp.intelliSenseEngine": "disabled",
"clangd.path": "/usr/bin/clangd",
"clangd.arguments":
[
"-log=verbose",
"-pretty",
"--background-index",
"--compile-commands-dir=${workspaceFolder}/compile_commands.json"
]
}
+6
View File
@@ -0,0 +1,6 @@
include $(MAKE_HOME)/defaults.mk
# Environment
CC=clang
CCC=clang++
CXX=clang++
+2
View File
@@ -0,0 +1,2 @@
vstsdk2.4
+6
View File
@@ -0,0 +1,6 @@
CONFIG ?= release
PKG_VER := vstsdk2.4
include pkg.mk
+40
View File
@@ -0,0 +1,40 @@
BUILD_DIR := ./build/${CONFIG}
PKG_ROOT := ./${PKG_VER}
OBJS := $(addprefix ${BUILD_DIR}/, $(subst .cpp,.o,$(SRCS)))
.PHONY: ${PKG_VER}.patch
all: ${PKG_ROOT}
prepare: ${PKG_ROOT}
patch: ${PKG_VER}.patch
${PKG_VER}.patch:
@rm -rf temp
@unzip ${PKG_VER}.zip -d temp >/dev/null
@diff -ruN temp/${PKG_VER}/ ${PKG_ROOT} > ${PKG_VER}.patch; [ $$? -eq 1 ]
@rm -rf temp
@echo "Created" ${PKG_VER}.patch
CXXFLAGS += -std=c++11
CXXFLAGS_debug := ${CXXFLAGS} -O0 -g
CXXFLAGS_release := ${CXXFLAGS} -O2
INCLUDES += -I./ -I/usr/include/freetype2
DEFINES += -D${TARGET}
${OBJS}: $(BUILD_DIR)/%.o : ${PKG_ROOT}/%.cpp
mkdir -p $(dir $@)
g++ ${CXXFLAGS_${CONFIG}} ${DEFINES} ${INCLUDES} -o $@ -c $<
${PKG_ROOT}:
unzip ${PKG_VER}.zip
if [ -e ${PKG_VER}.patch ]; then \
patch -p0 < ${PKG_VER}.patch;\
fi
clean:
rm -rf ${BUILD_DIR}/*
distclean:
rm -rf ${BUILD_DIR}
rm -rf ${PKG_ROOT}
+24
View File
@@ -0,0 +1,24 @@
diff -ruN temp/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp ./vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp
--- temp/vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp 2006-06-07 09:22:02.000000000 +0200
+++ ./vstsdk2.4/public.sdk/source/vst2.x/audioeffect.cpp 2025-08-02 10:01:34.082302630 +0200
@@ -7,7 +7,7 @@
// Created by : Steinberg Media Technologies
// Description : Class AudioEffect (VST 1.0)
//
-// © 2006, Steinberg Media Technologies, All Rights Reserved
+// � 2006, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------
#include "audioeffect.h"
@@ -507,9 +507,10 @@
{
VstInt32 digit = value / div;
value -= digit * div;
+ const char digit8 = (char)(digit & 0xFF) + '0';
if (state || digit > 0)
{
- char temp[2] = {'0' + (char)digit, '\0'};
+ char temp[2] = {digit8, '\0'};
vst_strncat (text, temp, maxLen);
state = true;
}
Binary file not shown.
Executable
+225
View File
@@ -0,0 +1,225 @@
/*************************************************************************/
/* iir.c
/*************************************************************************/
#include "stdio.h"
#include "math.h"
#include "iir.h"
/*************************************************************************/
/* Global Variables
/*************************************************************************/
const char *filterTypeString[] =
{
"Unknown filter type",
"Butterworth-Lowpass",
"Butterworth-Highpass",
"Butterworth-Bandpass",
"Butterworth-Bandstop",
"Peaking-EQ",
"Low Shelving-EQ",
"High Shelving-EQ"
};
/******************************************************************************/
void IIRCalcFilterCoeff(struct _sIIRCoeff *pCoeff, float fa, float fg, float q, unsigned order, unsigned filterType)
{
unsigned p;
float qp;
//IIRInit(pCoeff, order);
for(p=0; p < order/2;p++)
{
qp = q * IIRCalcQp(p+1, order);
IIRCalcPartFilterCoeff2(&pCoeff[p], 1.0, fa, fg, qp, filterType);
}
}
int IIRCalcPartFilterCoeff1(struct _sIIRCoeff *pCoeff, float fa, float fg, float Qi, unsigned filterType)
{
float K, a0;
float alpha, omega, ks, kc;
unsigned error;
omega = (float)(2*pi*fg/fa);
ks = (float)sin(omega);
kc = (float)cos(omega);
alpha = (float)(0.5*ks /Qi);
K = IIRBilTrans(fg, fa);
a0 = K/Qi + 1;
switch(filterType)
{
case IIR_FILTERTYPE_LOWPASS:
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (1 - K/Qi)/a0;
pCoeff->ak2 = 0.0;
pCoeff->bk0 = (float)(1.0/a0);
pCoeff->bk1 = (float)(1.0/a0);
pCoeff->bk2 = (float)0.0;
break;
case IIR_FILTERTYPE_HIGHPASS:
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (1 - K/Qi) /a0;
pCoeff->ak2 = 0.0;
pCoeff->bk0 = (float)(1.0*K /a0);
pCoeff->bk1 = (float)(-1.0*K /a0);
pCoeff->bk2 = (float)0.0;
break;
default:
error = -1;
break;
}
return error;
}
int IIRCalcPartFilterCoeff2(struct _sIIRCoeff *pCoeff, float A, float fa, float fg, float qp, unsigned filterType)
{
float a0;
float alpha, omega, ks, kc;
unsigned error;
omega = (float)(2*pi*fg/fa);
ks = (float)sin(omega);
kc = (float)cos(omega);
alpha = (float)(0.5*ks /qp);
error = 0;
switch(filterType)
{
case IIR_FILTERTYPE_LOWPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(0.5*(1 - kc) /a0);
pCoeff->bk1 = (1 - kc) /a0;
pCoeff->bk2 = (float)(0.5*(1 - kc) /a0);
break;
case IIR_FILTERTYPE_HIGHPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(0.5*(1 + kc) /a0);
pCoeff->bk1 = -(1 + kc) /a0;
pCoeff->bk2 = (float)(0.5*(1 + kc) /a0);
break;
case IIR_FILTERTYPE_BANDPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = alpha /a0;
pCoeff->bk1 = 0;
pCoeff->bk2 = -alpha /a0;
break;
case IIR_FILTERTYPE_BANDSTOP:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(1.0 /a0);
pCoeff->bk1 = (float)(-2.0*kc /a0);
pCoeff->bk2 = (float)(1.0 /a0);
break;
case IIR_FILTERTYPE_PEAKING:
a0 = 1 + (alpha/A);
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - (alpha/A)) /a0;
pCoeff->bk0 = (1 + (alpha*A)) /a0;
pCoeff->bk1 = (float)(-2.0*kc /a0);
pCoeff->bk2 = (1 - (alpha*A)) /a0;
break;
default:
error = -1;
break;
}
return error;
}
void IIR(struct _sIIRCoeff *pCoeff, float *xn, float *yn, unsigned order, unsigned numPoints)
{
float xp, yp;
unsigned i, p;
unsigned numSec = order/2;
for (i=0; i<numPoints; i++)
{
xp = xn[i];
for (p=0; p < numSec; p++)
{
yp = pCoeff[p].bk0*xp
+ pCoeff[p].bk1*pCoeff[p].xn1
+ pCoeff[p].bk2*pCoeff[p].xn2
- pCoeff[p].ak1*pCoeff[p].yn1
- pCoeff[p].ak2*pCoeff[p].yn2;
pCoeff[p].yn2 = pCoeff[p].yn1;
pCoeff[p].yn1 = yp;
pCoeff[p].xn2 = pCoeff[p].xn1;
pCoeff[p].xn1 = xp;
xp = yp;
}
yn[i] = yp;
}
}
void IIRInit(struct _sIIRCoeff *pCoeff, unsigned order)
{
unsigned n;
for(n=0; n < order/2; n++)
{
pCoeff[n].ak0 = 0;
pCoeff[n].ak1 = 0;
pCoeff[n].ak2 = 0;
pCoeff[n].bk0 = 0;
pCoeff[n].bk1 = 0;
pCoeff[n].bk2 = 0;
pCoeff[n].xn1 = 0;
pCoeff[n].xn2 = 0;
pCoeff[n].yn1 = 0;
pCoeff[n].yn2 = 0;
}
}
float IIRBilTrans(float fg, float fa)
{
return (float)(1.0/(tan(pi*fg/fa)));
}
float IIRCalcQp(unsigned p, unsigned N)
{
return (float)(1.0/(2*sin(pi*(2*p-1)/(2*N))));
}
Executable
+68
View File
@@ -0,0 +1,68 @@
/******************************************************************************/
/* iir.h
/******************************************************************************/
#ifndef IIR_H
#define IIR_H
#define pi 3.1415926535897932384626433832795
#define IIR_FILTERTYPE_UNKNOWN 0x00000000
#define IIR_FILTERTYPE_LOWPASS 0x00000001
#define IIR_FILTERTYPE_HIGHPASS 0x00000002
#define IIR_FILTERTYPE_BANDPASS 0x00000003
#define IIR_FILTERTYPE_BANDSTOP 0x00000004
#define IIR_FILTERTYPE_PEAKING 0x00000005
#define IIR_FILTERTYPE_LOWSHELF 0x00000006
#define IIR_FILTERTYPE_HIGHSHELF 0x00000007
#if defined(__cplusplus)
extern "C" {
#endif
/******************************************************************************/
typedef struct _sComplex
{
float pRealData, pImagData;
} Complex;
typedef struct _sIIRCoeff
{
float ak0, ak1, ak2;
float bk0, bk1, bk2;
float xn1, xn2;
float yn1, yn2;
}IIRCOEFF;
typedef struct _sIIRParam
{
/* General Params */
float fg, Qf;
/* for shelving EQs */
float beta;
/* for peaking and shelving EQs */
float A;
}IIRPARAM;
/******************************************************************************/
void IIRInit(struct _sIIRCoeff *pCoeff, unsigned order);
int IIRCalcPartFilterCoeff1(struct _sIIRCoeff *pCoeff, float fa, float fg, float qp, unsigned filterType);
int IIRCalcPartFilterCoeff2(struct _sIIRCoeff *pCoeff, float A, float fa, float fg, float qp, unsigned filterType);
void IIRCalcFilterCoeff(struct _sIIRCoeff *pCoeff, float fa, float fg, float q, unsigned order, unsigned filterType);
float IIRBilTrans(float fg, float fa);
float IIRCalcQp(unsigned p, unsigned N);
void IIR(struct _sIIRCoeff *pCoeff, float *xn, float *yn, unsigned order, unsigned numPoints);
void IIRPrintCoeff(FILE *pFile, struct _sIIRCoeff *pCoeff, unsigned N);
void ScaleCoeff(struct _sIIRCoeff *pCoeff);
float MinMag(float val1, float val2);
float MaxMag(float val1, float val2);
/******************************************************************************/
#if defined(__cplusplus)
}
#endif
#endif /* IIR_H */
+25
View File
@@ -0,0 +1,25 @@
include ../make/defaults.mk
NAME := Vitalisierer
CONFIG ?= release
TARGET ?= JayVitalisierer.so
CFLAGS += -fPIC
CXXFLAGS += -fPIC
CXXFLAGS += -std=c++11
VST2_SDK_PATH := $(realpath ../sdk/vst/vstsdk2.4)
INCLUDES += -I $(realpath .)
INCLUDES += -I $(VST2_SDK_PATH)
DEFINES += -DVST_2_4_EXTENSIONS=0 -DVST_2_3_EXTENSIONS=1
GCC_SRCS := iir.c paramutils.c
CXX_SRCS := VitalisiererMain.cpp Vitalisierer2.cpp
CXX_SRCS += $(VST2_SDK_PATH)/public.sdk/source/vst2.x/audioeffect.cpp
CXX_SRCS += $(VST2_SDK_PATH)/public.sdk/source/vst2.x/audioeffectx.cpp
LIBS := -lstdc++
LDFLAGS += $(TARGET_ARCH) $(LIBDIR) -shared
include $(MAKE_HOME)/compile.mk
include $(MAKE_HOME)/link.mk
View File
Executable
+275
View File
@@ -0,0 +1,275 @@
/*-----------------------------------------------------------------------------
© 1999, Steinberg Soft und Hardware GmbH, All Rights Reserved
-----------------------------------------------------------------------------*/
#include <windows.h>
#include <stdio.h>
#include "iir.h"
#include "filter.hpp"
#include "paramutils.h"
#define NUM_PARMS 7
#define MAX_ORDER 10
#define MAX_TYPES 4
#define MAX_Q 10.0f
#define ALPHA 0.2f
#define BETA (1.0f-ALPHA)
char *pFTypeString[] =
{
"Unknown",
"Lowpass",
"Highpass",
"Bandpass",
"Bandstop",
"Peaking",
"Low-Shelving",
"High-Shelving"
};
enum {ORDER, TYPE, FMIN, FMAX, FG, Q, TESTPARAM};
char *pParmStr[NUM_PARMS] = {"Order","Filter-Type","Freq min","Freq max","Frequency","Resonance","Test-Param"};
AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{
return new Filter (audioMaster);
}
//-----------------------------------------------------------------------------
Filter::Filter(audioMasterCallback audioMaster)
: AudioEffectX(audioMaster, 1, NUM_PARMS) // 1 program, 1 parameter only
{
sampleRate = 48000;
fg = 1000/sampleRate; // default to 1000 Hz
order = 4;
q = 1.0f/MAX_Q;
type = IIR_FILTERTYPE_LOWPASS;
setNumInputs(2); // stereo in
setNumOutputs(2); // stereo out
setUniqueID('Filt'); // identify
// canMono(); // makes sense to feed both inputs with the same signal
canProcessReplacing(); // supports both accumulating and replacing output
strcpy(programName, "Default"); // default program name
IIRInit(filterCoeff_L, order);
IIRInit(filterCoeff_R, order);
sm_fg = fg;
sm_q = q;
testParam=0;
IIRCalcFilterCoeff(filterCoeff_L, sampleRate, sm_fg*sampleRate, sm_q, order, type);
IIRCalcFilterCoeff(filterCoeff_R, sampleRate, sm_fg*sampleRate, sm_q, order, type);
forder = (0.5f/MAX_ORDER)*(float)(order -1);
ftype = (1.0f/MAX_TYPES)*(float)(type -1);
f_fmin = 0;
f_fmax = 17300.f/sampleRate;
}
//-----------------------------------------------------------------------------------------
Filter::~Filter()
{
// nothing to do here
}
//-----------------------------------------------------------------------------------------
void Filter::setProgramName(char *name)
{
strcpy(programName, name);
}
//-----------------------------------------------------------------------------------------
void Filter::getProgramName(char *name)
{
strcpy(name, programName);
}
//-----------------------------------------------------------------------------------------
void Filter::setParameter(VstInt32 index, float value)
{
fg = f_fmin + value*(f_fmax-f_fmin);
switch(index)
{
case TYPE:
ftype = ParamQuantize(value,1.0f/(MAX_TYPES-1));
type = 1 + (VstInt32)(ftype*(MAX_TYPES-1));
IIRCalcFilterCoeff(filterCoeff_L, sampleRate, 0.5f*fg*sampleRate, q*MAX_Q, order, type);
IIRCalcFilterCoeff(filterCoeff_R, sampleRate, 0.5f*fg*sampleRate, q*MAX_Q, order, type);
break;
case ORDER:
forder = ParamQuantize(value,1.0f/(MAX_ORDER/2-1));
order = 2*(VstInt32)(1+forder*MAX_ORDER/2);
sprintf(dbgStr, "value = %f, forder = %f, order = %d",value,forder,order);
OutputDebugString(dbgStr);
IIRCalcFilterCoeff(filterCoeff_L, sampleRate, 0.5f*fg*sampleRate, q*MAX_Q, order, type);
IIRCalcFilterCoeff(filterCoeff_R, sampleRate, 0.5f*fg*sampleRate, q*MAX_Q, order, type);
break;
case FMIN:
f_fmin = value;
break;
case FMAX:
f_fmax = value;
break;
case FG:
f_fg_param = value;
break;
case Q:
q = value;
break;
case TESTPARAM:
testParam=ParamQuantize(value,1.0f/3);
sprintf(dbgStr, "Set Param: %f",value);
OutputDebugString(dbgStr);
break;
}
}
//-----------------------------------------------------------------------------------------
float Filter::getParameter(VstInt32 index)
{
float value = 0;
switch(index)
{
case TYPE:
value = (float)ftype;
break;
case ORDER:
value = (float)forder;
break;
case FMIN:
value = f_fmin;
break;
case FMAX:
value = f_fmin;
break;
case FG:
value = f_fg_param;
break;
case Q:
value = q;
break;
case TESTPARAM:
value = testParam;
sprintf(dbgStr, "Get Param: %f",value);
OutputDebugString(dbgStr);
break;
}
return value;
}
//-----------------------------------------------------------------------------------------
void Filter::getParameterName(VstInt32 index, char *label)
{
strcpy(label,pParmStr[index]);
}
//-----------------------------------------------------------------------------------------
void Filter::getParameterDisplay(VstInt32 index, char *text)
{
switch(index)
{
case TYPE:
strcpy(text,pFTypeString[type]);
break;
case ORDER:
int2string(order, text, kVstMaxParamStrLen);
break;
case FMIN:
float2string(0.5f*f_fmin*sampleRate,text, kVstMaxParamStrLen);
break;
case FMAX:
float2string(0.5f*f_fmax*sampleRate,text, kVstMaxParamStrLen);
break;
case FG:
float2string(0.5f*fg*sampleRate,text, kVstMaxParamStrLen);
break;
case Q:
float2string(q*MAX_Q,text, kVstMaxParamStrLen);
break;
case TESTPARAM:
float2string(testParam,text, kVstMaxParamStrLen);
break;
}
}
//-----------------------------------------------------------------------------------------
void Filter::getParameterLabel(VstInt32 index, char *label)
{
switch(index)
{
case TYPE:
strcpy(label, " ");
break;
case ORDER:
strcpy(label, " ");
break;
case FMIN:
strcpy(label, " Hz ");
break;
case FMAX:
strcpy(label, " Hz ");
break;
case FG:
strcpy(label, " Hz ");
break;
case Q:
strcpy(label, " ");
break;
case TESTPARAM:
strcpy(label, " Test ");
break;
}
}
//-----------------------------------------------------------------------------------------
void Filter::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames)
{
float *in1 = inputs[0];
float *in2 = inputs[1];
float *out1 = outputs[0];
float *out2 = outputs[1];
sm_fg = BETA*sm_fg+ALPHA*fg;
sm_q = BETA*sm_q+ALPHA*q*MAX_Q;
IIRCalcFilterCoeff(filterCoeff_L, sampleRate, 0.5f*sm_fg*sampleRate, sm_q, order, type);
IIRCalcFilterCoeff(filterCoeff_R, sampleRate, 0.5f*sm_fg*sampleRate, sm_q, order, type);
IIR(filterCoeff_L, in1, out1, order, sampleFrames);
IIR(filterCoeff_R, in2, out2, order, sampleFrames);
}
//-----------------------------------------------------------------------------------------
void Filter::setSampleRate(float sampleRate)
{
this->sampleRate = sampleRate;
sprintf(dbgStr, "Sample Rate = %f",sampleRate);
OutputDebugString(dbgStr);
}
//-----------------------------------------------------------------------------------------
void Filter::setBlockSize(VstInt32 blockSize)
{
this->blockSize = blockSize;
sprintf(dbgStr, "Block Size = %d",blockSize);
OutputDebugString(dbgStr);
}
Executable
+44
View File
@@ -0,0 +1,44 @@
/*-----------------------------------------------------------------------------
© 1999, Steinberg Soft und Hardware GmbH, All Rights Reserved
-----------------------------------------------------------------------------*/
#ifndef __FILTER_H
#define __FILTER_H
#include "public.sdk/source/vst2.x/audioeffectx.h"
class Filter : public AudioEffectX
{
public:
Filter(audioMasterCallback audioMaster);
~Filter();
// Processing
virtual void processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames);
// Program
virtual void setProgramName (char* name);
virtual void getProgramName (char* name);
// Parameters
virtual void setParameter (VstInt32 index, float value);
virtual float getParameter (VstInt32 index);
virtual void getParameterLabel (VstInt32 index, char* label);
virtual void getParameterDisplay (VstInt32 index, char* text);
virtual void getParameterName (VstInt32 index, char* text);
virtual void setSampleRate(float sampleRate);
virtual void setBlockSize(VstInt32 blockSize);
protected:
float ftype, forder, fg, q, sm_fg, sm_q, testParam;
float f_fmin, f_fmax, f_fg_param;
VstInt32 type, order;
char programName[32];
char dbgStr[80];
IIRPARAM filterParms;
IIRCOEFF filterCoeff_L[8], filterCoeff_R[8];
};
#endif
+56
View File
@@ -0,0 +1,56 @@
/*-----------------------------------------------------------------------------
© 1999, Steinberg Soft und Hardware GmbH, All Rights Reserved
-----------------------------------------------------------------------------*/
#include <stdio.h>
#include "iir.h"
#include "filter.hpp" // *change*
static AudioEffect *effect = 0;
bool oome = false;
#if MAC
#pragma export on
#endif
// prototype of the export function main
#if BEOS
#define main main_plugin
extern "C" __declspec(dllexport) AEffect *main_plugin (audioMasterCallback audioMaster);
#else
AEffect *main (audioMasterCallback audioMaster);
#endif
AEffect *main (audioMasterCallback audioMaster)
{
// get vst version
if (!audioMaster (0, audioMasterVersion, 0, 0, 0, 0))
return 0; // old version
effect = new Filter (audioMaster);
if (!effect)
return 0;
if (oome)
{
delete effect;
return 0;
}
return effect->getAeffect ();
}
#if MAC
#pragma export off
#endif
#if WIN32
#include <windows.h>
void* hInstance;
BOOL WINAPI DllMain (HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
{
hInstance = hInst;
return 1;
}
#endif
+225
View File
@@ -0,0 +1,225 @@
/*************************************************************************
** iir.c
**************************************************************************/
#include "stdio.h"
#include "math.h"
#include "iir.h"
/*************************************************************************
** Global Variables
**************************************************************************/
const char *filterTypeString[] =
{
"Unknown filter type",
"Butterworth-Lowpass",
"Butterworth-Highpass",
"Butterworth-Bandpass",
"Butterworth-Bandstop",
"Peaking-EQ",
"Low Shelving-EQ",
"High Shelving-EQ"
};
/******************************************************************************/
void IIRCalcFilterCoeff(struct _sIIRCoeff *pCoeff, float fa, float fg, float q, unsigned order, unsigned filterType)
{
unsigned p;
float qp;
//IIRInit(pCoeff, order);
for(p=0; p < order/2;p++)
{
qp = q * IIRCalcQp(p+1, order);
IIRCalcPartFilterCoeff2(&pCoeff[p], 1.0, fa, fg, qp, filterType);
}
}
int IIRCalcPartFilterCoeff1(struct _sIIRCoeff *pCoeff, float fa, float fg, float Qi, unsigned filterType)
{
float K, a0;
float alpha, omega, ks, kc;
unsigned error;
omega = (float)(2*pi*fg/fa);
ks = (float)sin(omega);
kc = (float)cos(omega);
alpha = (float)(0.5*ks /Qi);
K = IIRBilTrans(fg, fa);
a0 = K/Qi + 1;
switch(filterType)
{
case IIR_FILTERTYPE_LOWPASS:
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (1 - K/Qi)/a0;
pCoeff->ak2 = 0.0;
pCoeff->bk0 = (float)(1.0/a0);
pCoeff->bk1 = (float)(1.0/a0);
pCoeff->bk2 = (float)0.0;
break;
case IIR_FILTERTYPE_HIGHPASS:
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (1 - K/Qi) /a0;
pCoeff->ak2 = 0.0;
pCoeff->bk0 = (float)(1.0*K /a0);
pCoeff->bk1 = (float)(-1.0*K /a0);
pCoeff->bk2 = (float)0.0;
break;
default:
error = -1;
break;
}
return error;
}
int IIRCalcPartFilterCoeff2(struct _sIIRCoeff *pCoeff, float A, float fa, float fg, float qp, unsigned filterType)
{
float a0;
float alpha, omega, ks, kc;
unsigned error;
omega = (float)(2*pi*fg/fa);
ks = (float)sin(omega);
kc = (float)cos(omega);
alpha = (float)(0.5*ks /qp);
error = 0;
switch(filterType)
{
case IIR_FILTERTYPE_LOWPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(0.5*(1 - kc) /a0);
pCoeff->bk1 = (1 - kc) /a0;
pCoeff->bk2 = (float)(0.5*(1 - kc) /a0);
break;
case IIR_FILTERTYPE_HIGHPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(0.5*(1 + kc) /a0);
pCoeff->bk1 = -(1 + kc) /a0;
pCoeff->bk2 = (float)(0.5*(1 + kc) /a0);
break;
case IIR_FILTERTYPE_BANDPASS:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = alpha /a0;
pCoeff->bk1 = 0;
pCoeff->bk2 = -alpha /a0;
break;
case IIR_FILTERTYPE_BANDSTOP:
a0 = 1 + alpha;
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - alpha) /a0;
pCoeff->bk0 = (float)(1.0 /a0);
pCoeff->bk1 = (float)(-2.0*kc /a0);
pCoeff->bk2 = (float)(1.0 /a0);
break;
case IIR_FILTERTYPE_PEAKING:
a0 = 1 + (alpha/A);
pCoeff->ak0 = 1.0;
pCoeff->ak1 = (float)(-2.0*kc /a0);
pCoeff->ak2 = (1 - (alpha/A)) /a0;
pCoeff->bk0 = (1 + (alpha*A)) /a0;
pCoeff->bk1 = (float)(-2.0*kc /a0);
pCoeff->bk2 = (1 - (alpha*A)) /a0;
break;
default:
error = -1;
break;
}
return error;
}
void IIR(struct _sIIRCoeff *pCoeff, float *xn, float *yn, unsigned order, unsigned numPoints)
{
float xp, yp;
unsigned i, p;
unsigned numSec = order/2;
for (i=0; i<numPoints; i++)
{
xp = xn[i];
for (p=0; p < numSec; p++)
{
yp = pCoeff[p].bk0*xp
+ pCoeff[p].bk1*pCoeff[p].xn1
+ pCoeff[p].bk2*pCoeff[p].xn2
- pCoeff[p].ak1*pCoeff[p].yn1
- pCoeff[p].ak2*pCoeff[p].yn2;
pCoeff[p].yn2 = pCoeff[p].yn1;
pCoeff[p].yn1 = yp;
pCoeff[p].xn2 = pCoeff[p].xn1;
pCoeff[p].xn1 = xp;
xp = yp;
}
yn[i] = yp;
}
}
void IIRInit(struct _sIIRCoeff *pCoeff, unsigned order)
{
unsigned n;
for(n=0; n < order/2; n++)
{
pCoeff[n].ak0 = 0;
pCoeff[n].ak1 = 0;
pCoeff[n].ak2 = 0;
pCoeff[n].bk0 = 0;
pCoeff[n].bk1 = 0;
pCoeff[n].bk2 = 0;
pCoeff[n].xn1 = 0;
pCoeff[n].xn2 = 0;
pCoeff[n].yn1 = 0;
pCoeff[n].yn2 = 0;
}
}
float IIRBilTrans(float fg, float fa)
{
return (float)(1.0/(tan(pi*fg/fa)));
}
float IIRCalcQp(unsigned p, unsigned N)
{
return (float)(1.0/(2*sin(pi*(2*p-1)/(2*N))));
}
+68
View File
@@ -0,0 +1,68 @@
/******************************************************************************
** iir.h
*******************************************************************************/
#ifndef IIR_H
#define IIR_H
#define pi 3.1415926535897932384626433832795
#define IIR_FILTERTYPE_UNKNOWN 0x00000000
#define IIR_FILTERTYPE_LOWPASS 0x00000001
#define IIR_FILTERTYPE_HIGHPASS 0x00000002
#define IIR_FILTERTYPE_BANDPASS 0x00000003
#define IIR_FILTERTYPE_BANDSTOP 0x00000004
#define IIR_FILTERTYPE_PEAKING 0x00000005
#define IIR_FILTERTYPE_LOWSHELF 0x00000006
#define IIR_FILTERTYPE_HIGHSHELF 0x00000007
#if defined(__cplusplus)
extern "C" {
#endif
/******************************************************************************/
typedef struct _sComplex
{
float pRealData, pImagData;
} Complex;
typedef struct _sIIRCoeff
{
float ak0, ak1, ak2;
float bk0, bk1, bk2;
float xn1, xn2;
float yn1, yn2;
}IIRCOEFF;
typedef struct _sIIRParam
{
/* General Params */
float fg, Qf;
/* for shelving EQs */
float beta;
/* for peaking and shelving EQs */
float A;
}IIRPARAM;
/******************************************************************************/
void IIRInit(struct _sIIRCoeff *pCoeff, unsigned order);
int IIRCalcPartFilterCoeff1(struct _sIIRCoeff *pCoeff, float fa, float fg, float qp, unsigned filterType);
int IIRCalcPartFilterCoeff2(struct _sIIRCoeff *pCoeff, float A, float fa, float fg, float qp, unsigned filterType);
void IIRCalcFilterCoeff(struct _sIIRCoeff *pCoeff, float fa, float fg, float q, unsigned order, unsigned filterType);
float IIRBilTrans(float fg, float fa);
float IIRCalcQp(unsigned p, unsigned N);
void IIR(struct _sIIRCoeff *pCoeff, float *xn, float *yn, unsigned order, unsigned numPoints);
void IIRPrintCoeff(FILE *pFile, struct _sIIRCoeff *pCoeff, unsigned N);
void ScaleCoeff(struct _sIIRCoeff *pCoeff);
float MinMag(float val1, float val2);
float MaxMag(float val1, float val2);
/******************************************************************************/
#if defined(__cplusplus)
}
#endif
#endif /* IIR_H */
+28
View File
@@ -0,0 +1,28 @@
#include <math.h>
float ParamQuantize(float value, float quantization)
{
float result = 1.0;
float k = (float) ceil(value / quantization);
if ((k*quantization) < 1.0)
result = k*quantization;
return result;
}
float norm2quant(float minparm, float maxparm, float quant, float x)
{
int y;
float step = (maxparm-minparm);
y = (int)minparm + (int)quant * (int)((0.5 + x*step)/quant);
return (float)y;
}
float quant2norm(float minparm, float maxparm, float y)
{
return (y-minparm)/(maxparm-minparm);
}
+21
View File
@@ -0,0 +1,21 @@
/***************************************************************
** paramutils.h
****************************************************************/
#ifndef PARAMUTILS_H
#define PARAMUTILS_H
#if defined(__cplusplus)
extern "C" {
#endif
/***************************************************************/
float ParamQuantize(float value, float quantization);
float norm2quant(float minparm, float maxparm, float quant, float x);
float quant2norm(float minparm, float maxparm, float y);
/***************************************************************/
#if defined(__cplusplus)
}
#endif /* cplusplus */
#endif /* PARAMUTILS_H */
+1
Submodule submodules/make added at e07fbf1860