Skip to content

Instantly share code, notes, and snippets.

@zeffii
Created May 9, 2016 10:10
Show Gist options
  • Save zeffii/873694d638ccadd6dff1802f73500e75 to your computer and use it in GitHub Desktop.
Save zeffii/873694d638ccadd6dff1802f73500e75 to your computer and use it in GitHub Desktop.
code conservation.
#include "../MachineInterface.h"
#include <windows.h>
#include <math.h>
#include <float.h>
#pragma optimize ("awy", on)
CMachineParameter const paraCutoff =
{
pt_word, // Parameter data type
"Cutoff", // Parameter name as its shown in the parameter window
"Filter Cutoff", // Parameter description as its shown in the pattern view's statusbar
0, // Minimum value
22050, // Maximum value
0xFFFF, // Novalue, this value means "nothing happened" in the mi::Tick procedure
MPF_STATE, // Parameter options, MPF_STATE makes it appears as a slider
22050 // the default slider value
};
CMachineParameter const paraResonance =
{
pt_byte, // Parameter data type
"Resonance", // Parameter name as its shown in the parameter window
"Filter Resonance", // Parameter description as its shown in the pattern view's statusbar
1, // Minimum value
0xFE, // Maximum value
0xFF, // Novalue, this value means "nothing happened" in the mi::Tick procedure
MPF_STATE, // Parameter options, MPF_STATE makes it appears as a slider
0x0 // the default slider value
};
CMachineParameter const *pParameters[] = {
&paraCutoff,
&paraResonance
};
CMachineAttribute const *pAttributes[] = { NULL };
#pragma pack(1)
class gvals
{
public:
word cutoff;
byte resonance;
};
#pragma pack()
CMachineInfo const MacInfo =
{
MT_EFFECT, // Machine type
MI_VERSION, // Machine interface version
MIF_DOES_INPUT_MIXING, // Machine flags
0, // min tracks
0, // max tracks
2, // numGlobalParameters
0, // numTrackParameters
pParameters, // pointer to parameter stuff
0, // numAttributes
pAttributes, // pointer to attribute stuff
"Ome PFilter", // Full Machine Name
"PFilter", // Short name
"A BuzzDev Ex.", // Author name
"&About..." // Right click menu commands
};
class miex : public CMachineInterfaceEx { };
class mi : public CMachineInterface
{
public:
mi();
virtual ~mi();
virtual void Tick();
virtual void Init(CMachineDataInput * const pi);
virtual bool Work(float *psamples, int numsamples, int const mode);
virtual bool WorkMonoToStereo(float *psamples, int numsamples, int const mode);
virtual void Command(int const i);
virtual void Save(CMachineDataOutput * const po);
virtual char const *DescribeValue(int const param, int const value);
virtual CMachineInterfaceEx *GetEx() { return &ex; }
virtual void OutputModeChanged(bool stereo) {}
// Ma filtah here:
virtual void MaFiltah();
public:
miex ex;
public:
// Filter stuff
float param_cutoff, param_resonance;
float filtCoefTab[5];
float lx1, lx2, ly1, ly2; // Left sample history
float rx1, rx2, ry1, ry2; // Right sample history
gvals gval;
};
mi::mi() { GlobalVals = &gval; }
mi::~mi() { }
void mi::MaFiltah () {
float alpha, omega, sn, cs;
float a0, a1, a2, b0, b1, b2;
// These limits the cutoff frequency and resonance to
// reasoneable values.
if (param_cutoff < 20.0f) { param_cutoff = 20.0f; };
if (param_cutoff > 22000.0f) { param_cutoff = 22000.0f; };
if (param_resonance < 1.0f) { param_resonance = 1.0f; };
if (param_resonance > 127.0f) { param_resonance = 127.0f; };
omega = 2.0f * PI * param_cutoff/pMasterInfo->SamplesPerSec;
sn = sin (omega); cs = cos (omega);
alpha = sn / param_resonance;
b0 = (1.0f - cs) / 2.0f;
b1 = 1.0f - cs;
b2 = (1.0f - cs) / 2.0f;
a0 = 1.0f + alpha;
a1 = -2.0f * cs;
a2 = 1.0f - alpha;
filtCoefTab[0] = b0/a0;
filtCoefTab[1] = b1/a0;
filtCoefTab[2] = b2/a0;
filtCoefTab[3] = -a1/a0;
filtCoefTab[4] = -a2/a0;
}
void mi::Init(CMachineDataInput * const pi)
{
pCB->SetnumOutputChannels(pCB->GetThisMachine(), 2);
pCB->SetMachineInterfaceEx((CMachineInterfaceEx *)&ex);
param_cutoff = 22050;
param_resonance = 0;
MaFiltah ();
lx1 = lx2 = ly1 = ly2 = 0.0f;
rx1 = rx2 = ry1 = ry2 = 0.0f;
}
void mi::Save(CMachineDataOutput * const po) { }
void mi::Tick() {
if (gval.cutoff != 0xFFFF) {
param_cutoff = (float)gval.cutoff;
MaFiltah();
};
if (gval.resonance != 0xFF) {
param_resonance = ((float)gval.resonance / 2.0f);
MaFiltah();
};
}
bool mi::Work(float *psamples, int numsamples, int const mode)
{
return false;
}
bool mi::WorkMonoToStereo(float *psamples, int numsamples, int const mode)
{
if (mode==WM_WRITE)
return false;
if (mode==WM_NOIO)
return false;
if (mode==WM_READ) // <thru>
return true;
float inL, inR, outL, outR, temp_y;
int i;
for( i=0; i<numsamples*2; i++ ) {
inL = psamples[i];
inR = psamples[i+1];
outL = inL;
outR = inR;
// Left
temp_y = filtCoefTab[0] * outL +
filtCoefTab[1] * lx1 +
filtCoefTab[2] * lx2 +
filtCoefTab[3] * ly1 +
filtCoefTab[4] * ly2;
ly2 = ly1; ly1 = temp_y; lx2 = lx1; lx1 = outL ; outL = temp_y;
// Right
temp_y = filtCoefTab[0] * outR +
filtCoefTab[1] * rx1 +
filtCoefTab[2] * rx2 +
filtCoefTab[3] * ry1 +
filtCoefTab[4] * ry2;
ry2 = ry1; ry1 = temp_y; rx2 = rx1; rx1 = outR ; outR = temp_y;
psamples[i] = outL;
i++;
psamples[i] = outR;
};
return true;
}
void mi::Command(int const i)
{
switch (i)
{
case 0:
MessageBox(NULL,"PFilter 1.0\n\nThis is an example created from a buzzdev effects tutorial written by CyanPhase","About PFilter",MB_OK|MB_SYSTEMMODAL);
break;
default:
break;
}
}
char const *mi::DescribeValue(int const param, int const value)
{
static char txt[16];
switch(param)
{
case 0:
sprintf(txt,"%.1f", (float)value );
return txt;
break;
case 1:
sprintf(txt,"%.1f%%", ((float)value / 254.0f * 100.0f) );
return txt;
break;
default:
return NULL;
}
}
#pragma optimize ("", on)
DLL_EXPORTS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment