PDA

View Full Version : more than one instace = crackles, drops...


pylorca
08-18-2010, 08:34 PM
Hi,
I'm starting with wdl and iplug... thanks for this lib, it is amazing.


Two questions:

I'm getting bad sound (like drops, and crackles) when I use more than one instance of my plugin on reaper, but it sounds good when I use a single instance.

The reaper "performance meter" says 0.35% cpu when the music is playing, but when the music stops it says 2.4% cpu (This value remains until you press play again)

any comments would be appreciated, Thanks!


#include "PyEQ.h"
#include "../IPlug_include_in_plug_src.h"
#include "../IControl.h"
#include "resource.h"
#include "PulEQ.h"
#include <math.h>

const int kNumPrograms = 1;

PulEQ pul_l = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);
PulEQ pul_r = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);

enum EParams {

kLowFreq,
kLowBoost,
kLowAtten,

kMidGain,
kMidFreq,
kMidWidth,

kHiGain,
kNumParams,

};

enum ELowFreq {
k20 = 0,
k30,
k60,
k100,
kNumLowFreq
};

enum ELayout
{
kW = 627,
kH = 233,


kLowFreq_X = 82,
kLowFreq_Y = 140,

kLowBoost_X = 28,
kLowBoost_Y = 28,

kLowAtten_X = 126,
kLowAtten_Y = 28,

kMidGain_X = 256,
kMidGain_Y = 28,

kMidFreq_X = 262,
kMidFreq_Y = 138,

kHiGain_X = 390,
kHiGain_Y = 10,
};

void PyEQ::OnParamChange(int paramIdx)
{
double lowBoost = GetParam(kLowBoost)->Value();
double lowAtten = GetParam(kLowAtten)->Value();
int lowFreq = (int)GetParam(kLowFreq)->Value();
double midGain = GetParam(kMidGain)->Value();
double midFreq = GetParam(kMidFreq)->Value();

double hiGain = GetParam(kHiGain)->Value();

pul_l.setLowShelv(lowBoost, -lowAtten, lowFreq);
pul_r.setLowShelv(lowBoost, -lowAtten, lowFreq);

pul_l.setMid(midGain, midFreq, 1);
pul_r.setMid(midGain, midFreq, 1);

pul_l.setHiShelv(hiGain, 2);
pul_r.setHiShelv(hiGain, 2);

}


PyEQ::PyEQ(IPlugInstanceInfo instanceInfo)
: IPLUG_CTOR(kNumParams, 6, instanceInfo), prevL(0.0), prevR(0.0)
{
TRACE;

// Define parameter ranges, display units, labels.

GetParam(kLowBoost)->InitDouble("boost low", 0.0, 0.0, 16.0, 0.1, "dB");
GetParam(kLowAtten)->InitDouble("Atten low", 0.0, 0.0, 22.0, 1.3*0.15, "dB");

GetParam(kMidGain)->InitDouble("Mid Gain", 0.0, -12.0, 12.0, 0.1, "dB");
GetParam(kMidFreq)->InitDouble("Mid Freq", 2110, 150, 4000, 10, "dB");
GetParam(kHiGain)->InitDouble("Hi Gain", 0.0, -10.0, 10.0, 0.01, "dB");
GetParam(kLowFreq)->InitEnum("Low Freq", 1, kNumLowFreq); // Params can be enums.


MakePreset("preset 1", -5.0, 5.0, 17, 1);
MakePreset("preset 2", -15.0, 25.0, 37,1);
MakeDefaultPreset("-", 4);

// Instantiate a graphics engine.

IGraphics* pGraphics = MakeGraphics(this, kW, kH); // MakeGraphics(this, kW, kH);
pGraphics->AttachBackground(BG_ID, BG_FN);

// Attach a rotating knob associated with the Pan parameter.

IBitmap bitmap = pGraphics->LoadIBitmap(KNOB_ID, KNOB_FN, 71);
pGraphics->AttachControl(new IKnobMultiControl(this, kLowBoost_X, kLowBoost_Y, kLowBoost, &bitmap));
pGraphics->AttachControl(new IKnobMultiControl(this, kLowAtten_X, kLowAtten_Y, kLowAtten, &bitmap));
pGraphics->AttachControl(new IKnobMultiControl(this, kHiGain_X, kHiGain_Y , kHiGain, &bitmap));
pGraphics->AttachControl(new IKnobMultiControl(this, kMidGain_X, kMidGain_Y , kMidGain, &bitmap));

bitmap = pGraphics->LoadIBitmap(KNOB_MID_FREQ_ID, KNOB_MID_FREQ_FN, 35);
pGraphics->AttachControl(new IKnobMultiControl(this, kMidFreq_X, kMidFreq_Y , kMidFreq, &bitmap));

bitmap = pGraphics->LoadIBitmap(KNOB_SELECTOR_X4_ID, KNOB_SELECTOR_X4_FN, kNumLowFreq);
pGraphics->AttachControl(new IKnobMultiControl(this, kLowFreq_X, kLowFreq_Y , kLowFreq, &bitmap));

// Attach the graphics engine to the plugin.

AttachGraphics(pGraphics);

// No cleanup necessary, the graphics engine manages all of its resources and cleans up when closed.
}

void PyEQ::ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames)
{
// Mutex is already locked for us.

double* in1 = inputs[0];
double* in2 = inputs[1];
double* out1 = outputs[0];
double* out2 = outputs[1];

for (int s = 0; s < nFrames; ++s, ++in1, ++in2, ++out1, ++out2) {

pul_l.process(in1);
pul_r.process(in2);


*out1 = *in1;
*out2 = *in2;

}


}

RRokkenAudio
08-18-2010, 08:40 PM
Global stuff causing crosstalking,maybe put this :

PulEQ pul_l = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);
PulEQ pul_r = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);

in onparamchange... lemme know...

EDIT: Your getting denormals in your filter code. Inside your filter code, apply some noise to the input...ex:

1.0E-25f;
1.0E-25f;


Example
*in1 += 1.0E-25f;
*in2 += 1.0E-25f;


~Rob.

Xenakios
08-18-2010, 08:46 PM
Global stuff causing crosstalking,maybe put this :

PulEQ pul_l = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);
PulEQ pul_r = PulEQ(44100, 0, 0, 1, 0, 1, 0, 0, 1);

in onparamchange... lemme know...

~Rob.

That won't work in the OnParamChange method. Put the filter instances as class members of the plugin class. The reason for the multiple plugin instances problems is indeed that the original poster has put the filter objects as global variables.

RRokkenAudio
08-18-2010, 08:47 PM
ahh yeah xenakios, I didnt see the = there.. I usually just use SET to set the args in onparamchange..... Anyhow.. have fun with iPlug! Don't hesitate to ask stuff.. or provide cool source code lol..

~Rob.

pylorca
08-18-2010, 09:49 PM
Thanks guys!

With PulEQ as member of plugin class works fine.

:D

RRokkenAudio
08-18-2010, 10:10 PM
What filters you using for that btw?

Tale
08-19-2010, 12:35 AM
Your getting denormals in your filter code. Inside your filter code, apply some noise to the input...ex:

1.0E-25f;
1.0E-25f;

Example
*in1 += 1.0E-25f;
*in2 += 1.0E-25f;


Here is another (better?) way to get rid of denormals, using WDL's denormal.h:

#include "WDL/denormal.h"

...

denormal_fix_double(&mFilterOutput);

pylorca
08-19-2010, 10:22 AM
What filters you using for that btw?

bessel lp (to generate low shelv and hi shelv) and the peak is from Robert Bristow-Johnson cook-book.
I have to do oversample to get analog like phase near the nyquist, but still without success.


The reaper "performance meter" says 0.35% cpu when the music is playing, but when the music stops it says 2.4% cpu (This value remains until you press play again)

about this, the heavy process is in setLowShelv(), setHi, etc, but it is ony called in onParamChange(int)


EDIT:

Here is another (better?) way to get rid of denormals, using WDL's denormal.h:

#include "WDL/denormal.h"

...

denormal_fix_double(&mFilterOutput);

Why is that?

RRokkenAudio
08-19-2010, 10:57 AM
like I said, your filter is making denormals.. put that code in your filter .. either: denormal_fix_double(&mFilterOutput); or *in1 += 1.0E-25f; *in2 += 1.0E-25f; (whatever your filter requires, in or out, usually output)...

Pushes a small(inaudable) amount of noise down the chain, to avoid denormal number issues... Make sure to put denormal handling in EVERY filter you make..... actually right inside the filters input or output... I have some filters where it will work on input..and most of them work by denormalling the output..

This is the pull: pul_l.process(in1);
pul_r.process(in2);


Here's how I have my Filters setup with this:

class Filters
{
public:

Filters()
{
// reset filter coeffs
b0a0=b1a0=b2a0=a1a0=a2a0=0.0;

// reset in/out
ou1=ou2=in1=in2=0.0f;
};

float filter(float in0)
{
ou1 += 1.0E-25f;
ou2 += 1.0E-25f;

// filter
float const yn = b0a0*in0 + b1a0*in1 + b2a0*in2 - a1a0*ou1 - a2a0*ou2;

// push in/out
in2=in1;
in1=in0;
ou2=ou1;
ou1=yn;

// return output
return yn;
};


~Rob.

pylorca
08-19-2010, 11:35 AM
thanks Rob!

RRokkenAudio
08-19-2010, 04:39 PM
Oversampling is a bitch, I haven't gotten a working oversampling model yet, then down-sampling etc.. I tried to find a good class out there, not much luck. And at this point, the code i've tried on my own(zero stuffing) hasn't come out too well, lets just say that lol... Nothing like a +300db blast of noise in your ears hahaha.

~Rob.

pylorca
08-20-2010, 12:08 AM
Some test code in JS, Its works fine, is a 2x oversampling

The test: 10 khz sine with a waveshaper


without oversampling:

http://forum.cockos.com/attachment.php?attachmentid=8769&stc=1&d=1282287830

With oversampling, the aliasing is gone
http://forum.cockos.com/attachment.php?attachmentid=8770&stc=1&d=1282287830



slider1:0<0,1,1{OFF, ON}>Oversample
//slider2:2.825<-25,25,0.005>m_fgain
//slider3:0.3635<0,3,0.0005>Q
//slider4:10768<1000,20000,0.1>Freq
//slider4:4.1<-2,10,0.001>fgain

@slider

os = slider1;


@init
cAmpDB = 8.65617025;
os_out_vol = exp(0/cAmpDB);
compensation = exp(6.025/cAmpDB);


srate == 44100 ? (
/*
Filter type: Low Pass
Filter model: Chebyshev
Filter order: 16
Sampling Frequency: 88 KHz
Cut Frequency: 22.050000 KHz
Pass band Ripple: 0.120000 dB
Coefficents Quantization: float*/

ac0 = 0.00000054666269979534;
ac1 = 0.00000874660319672540;
ac2 = 0.00006559952397544050;
ac3 = 0.00030613111188538904;
ac4 = 0.00099492611362751444;
ac5 = 0.00238782267270603450;
ac6 = 0.00437767489996106290;
ac7 = 0.00625382128565866130;
ac8 = 0.00703554894636599420;
ac9 = 0.00625382128565866130;
ac10 = 0.00437767489996106290;
ac11 = 0.00238782267270603450;
ac12 = 0.00099492611362751444;
ac13 = 0.00030613111188538904;
ac14 = 0.00006559952397544050;
ac15 = 0.00000874660319672540;
ac16 = 0.00000054666269979534;

bc0 = 1.00000000000000000000;
bc1 = -6.59236256815257440000;
bc2 = 24.30359590473971600000;
bc3 = -63.00251767414410200000;
bc4 = 126.02363492199244000000;
bc5 = -203.69567059097182000000;
bc6 = 273.07506534627828000000;
bc7 = -308.14174394844491000000;
bc8 = 294.82085573852561000000;
bc9 = -239.52270379572360000000;
bc10 = 164.58880682189491000000;
bc11 = -94.70368652386916600000;
bc12 = 44.81299793908032600000;
bc13 = -16.91477670098831600000;
bc14 = 4.82928997469533260000;
bc15 = -0.94009053632209516000;
bc16 = 0.09550463080289756100;

iac0 = 1.38647821816089740000;
iac1 = -2.77295636596020720000;
iac2 = 1.38647821816089740000;
ibc0 = 1.00000000000000000000;
ibc1 = -1.99935901335328460000;
ibc2 =0.99935906408544817000;


);
srate == 48000 ? (
/*Filter type: Low Pass
Filter model: Chebyshev
Filter order: 16
Sampling Frequency: 96 KHz
Cut Frequency: 24.000000 KHz
Pass band Ripple: 0.120000 dB
Coefficents Quantization: float*/
xxxaaaaa=1;

);

@sample
inl = spl0;
inr = spl1;


os == 1 ? (

ps1 = inl*compensation;
ps2 = 0;


y = (ac0 * ps1) +
(ac1 * ixn1 - bc1 * iyn1) +
(ac2 * ixn2 - bc2 * iyn2) +
(ac3 * ixn3 - bc3 * iyn3) +
(ac4 * ixn4 - bc4 * iyn4) +
(ac5 * ixn5 - bc5 * iyn5) +
(ac6 * ixn6 - bc6 * iyn6) +
(ac7 * ixn7 - bc7 * iyn7) +
(ac8 * ixn8 - bc8 * iyn8) +
(ac9 * ixn9 - bc9 * iyn9) +
(ac10 * ixn10 - bc10 * iyn10) +
(ac11 * ixn11 - bc11 * iyn11) +
(ac12 * ixn12 - bc12 * iyn12) +
(ac13 * ixn13 - bc13 * iyn13) +
(ac14 * ixn14 - bc14 * iyn14) +
(ac15 * ixn15 - bc15 * iyn15) +
(ac16 * ixn16 - bc16 * iyn16);

ixn16 = ixn15; ixn15 = ixn14;ixn14 = ixn13;ixn13 = ixn12;ixn12 = ixn11;ixn11 = ixn10;
ixn10=ixn9;ixn9=ixn8; ixn8=ixn7; ixn7=ixn6; ixn6=ixn5; ixn5=ixn4; ixn4=ixn3; ixn3=ixn2; ixn2=ixn1; ixn1=ps1;

iyn16 = iyn15; iyn15 = iyn14;iyn14 = iyn13;iyn13 = iyn12;iyn12 = iyn11;iyn11 = iyn10;
iyn10=iyn9;iyn9=iyn8; iyn8=iyn7; iyn7=iyn6; iyn6=iyn5; iyn5=iyn4; iyn4=iyn3; iyn3=iyn2; iyn2=iyn1; iyn1=y;


y1 = (ac0 * ps2) +
(ac1 * ixn1 - bc1 * iyn1) +
(ac2 * ixn2 - bc2 * iyn2) +
(ac3 * ixn3 - bc3 * iyn3) +
(ac4 * ixn4 - bc4 * iyn4) +
(ac5 * ixn5 - bc5 * iyn5) +
(ac6 * ixn6 - bc6 * iyn6) +
(ac7 * ixn7 - bc7 * iyn7) +
(ac8 * ixn8 - bc8 * iyn8) +
(ac9 * ixn9 - bc9 * iyn9) +
(ac10 * ixn10 - bc10 * iyn10) +
(ac11 * ixn11 - bc11 * iyn11) +
(ac12 * ixn12 - bc12 * iyn12) +
(ac13 * ixn13 - bc13 * iyn13) +
(ac14 * ixn14 - bc14 * iyn14) +
(ac15 * ixn15 - bc15 * iyn15) +
(ac16 * ixn16 - bc16 * iyn16);

ixn16 = ixn15; ixn15 = ixn14;ixn14 = ixn13;ixn13 = ixn12;ixn12 = ixn11;ixn11 = ixn10;
ixn10=ixn9;ixn9=ixn8; ixn8=ixn7; ixn7=ixn6; ixn6=ixn5; ixn5=ixn4; ixn4=ixn3; ixn3=ixn2; ixn2=ixn1; ixn1=ps2;

iyn16 = iyn15; iyn15 = iyn14;iyn14 = iyn13;iyn13 = iyn12;iyn12 = iyn11;iyn11 = iyn10;
iyn10=iyn9;iyn9=iyn8; iyn8=iyn7; iyn7=iyn6; iyn6=iyn5; iyn5=iyn4; iyn4=iyn3; iyn3=iyn2; iyn2=iyn1; iyn1=y1;



fxout0l = atan(y) * 0.5*$pi;
fxout1l = atan(y1) * 0.5*$pi;


y = (ac0 * fxout0l) +
(ac1 * xn1 - bc1 * yn1) +
(ac2 * xn2 - bc2 * yn2) +
(ac3 * xn3 - bc3 * yn3) +
(ac4 * xn4 - bc4 * yn4) +
(ac5 * xn5 - bc5 * yn5) +
(ac6 * xn6 - bc6 * yn6) +
(ac7 * xn7 - bc7 * yn7) +
(ac8 * xn8 - bc8 * yn8) +
(ac9 * xn9 - bc9 * yn9) +
(ac10 * xn10 - bc10 * yn10) +
(ac11 * xn11 - bc11 * yn11) +
(ac12 * xn12 - bc12 * yn12) +
(ac13 * xn13 - bc13 * yn13) +
(ac14 * xn14 - bc14 * yn14) +
(ac15 * xn15 - bc15 * yn15) +
(ac16 * xn16 - bc16 * yn16);

xn16 = xn15; xn15 = xn14;xn14 = xn13;xn13 = xn12;xn12 = xn11;xn11 = xn10;
xn10=xn9;xn9=xn8; xn8=xn7; xn7=xn6; xn6=xn5; xn5=xn4; xn4=xn3; xn3=xn2; xn2=xn1; xn1=fxout0l;

yn16 = yn15; yn15 = yn14;yn14 = yn13;yn13 = yn12;yn12 = yn11;yn11 = yn10;
yn10=yn9;yn9=yn8; yn8=yn7; yn7=yn6; yn6=yn5; yn5=yn4; yn4=yn3; yn3=yn2; yn2=yn1; yn1=y;


y1 = (ac0 * fxout1l) +
(ac1 * xn1 - bc1 * yn1) +
(ac2 * xn2 - bc2 * yn2) +
(ac3 * xn3 - bc3 * yn3) +
(ac4 * xn4 - bc4 * yn4) +
(ac5 * xn5 - bc5 * yn5) +
(ac6 * xn6 - bc6 * yn6) +
(ac7 * xn7 - bc7 * yn7) +
(ac8 * xn8 - bc8 * yn8) +
(ac9 * xn9 - bc9 * yn9) +
(ac10 * xn10 - bc10 * yn10) +
(ac11 * xn11 - bc11 * yn11) +
(ac12 * xn12 - bc12 * yn12) +
(ac13 * xn13 - bc13 * yn13) +
(ac14 * xn14 - bc14 * yn14) +
(ac15 * xn15 - bc15 * yn15) +
(ac16 * xn16 - bc16 * yn16);

xn16 = xn15; xn15 = xn14;xn14 = xn13;xn13 = xn12;xn12 = xn11;xn11 = xn10;
xn10=xn9;xn9=xn8; xn8=xn7; xn7=xn6; xn6=xn5; xn5=xn4; xn4=xn3; xn3=xn2; xn2=xn1; xn1=fxout1l;

yn16 = yn15; yn15 = yn14;yn14 = yn13;yn13 = yn12;yn12 = yn11;yn11 = yn10;
yn10=yn9;yn9=yn8; yn8=yn7; yn7=yn6; yn6=yn5; yn5=yn4; yn4=yn3; yn3=yn2; yn2=yn1; yn1=y1;

spl0 =spl1= y*os_out_vol;

):(
spl0=spl1=atan(spl0) * 0.5*$pi;
);

RRokkenAudio
08-20-2010, 12:10 AM
oh lord... now i gotta port that lol... hey Thanks for the update man!

~Rob.

Tale
08-20-2010, 01:58 AM
Cool! :cool:

junioreq
11-03-2010, 10:43 PM
Did you manage to get the oversampling working in Iplug? I still have been lax on this :) Still kinda hard to understand for me what in that code is a coeff and what is the oversample, or is it all integrated?

~Rob.