• AVR Freaks

36 db resonant IIR filter needs adjustment

Author
JanJansen
Super Member
  • Total Posts : 530
  • Reward points : 0
  • Joined: 2012/08/25 03:26:34
  • Location: 0
  • Status: offline
2017/07/13 08:48:59 (permalink)
0

36 db resonant IIR filter needs adjustment

Hi, i was busy with making a resonant filter for synthesizers on DSPIC33FJ128GP802.
The resonance does not show in the upper part of the waveform, only the lower part.
Can someone tell me where i went wrong in making this filter ?

https://youtu.be/SeYqGejco9U
 
I try upload the source code in more posts :
 

//------------------------------------------------------------------------------
struct Pole32
{
long lastin;
long lastout; // also used as filter output
}pole1,pole2,pole3,pole4,pole5,pole6;

//------------------------------------------------------------------------------
#define ResetFilter( p )p.lastin = p.lastout = 0

unsigned short A32,B32;

void ( * HandleFilter )();

unsigned char reso = 127;

//------------------------------------------------------------------------------
#define ProcessLP( p , in , a , b ) \
lTemp = in; \
lTemp += p.lastin; \
lTemp *= a; \
lTemp >>= 15; \
\
lTemp2 = p.lastout; \
lTemp2 *= b; \
lTemp2 >>= 15; \
\
p.lastout = lTemp + lTemp2; \
p.lastin = in; \
 

post edited by JanJansen - 2017/07/13 08:53:52
#1

7 Replies Related Threads

    JanJansen
    Super Member
    • Total Posts : 530
    • Reward points : 0
    • Joined: 2012/08/25 03:26:34
    • Location: 0
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/13 08:50:04 (permalink)
    0

    //------------------------------------------------------------------------------
    // Handle LowPass Filter 36 db
    //------------------------------------------------------------------------------
    void HandleLP36()
    {
    A32 = ( 32768 - B32 ) >> 1;

    // 12 db
    lTemp = ( pole2.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole1 , lTemp2 , A32 , B32 )
    ProcessLP( pole2 , pole1.lastout , A32 , B32 )

    output = pole2.lastout * ( 128 + reso );
    output *= 3;
    output >>= 8;

    // 24 db
    lTemp = ( pole4.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole3 , lTemp2 , A32 , B32 )
    ProcessLP( pole4 , pole3.lastout , A32 , B32 )

    output = pole4.lastout * ( 128 + reso );
    output *= 5;
    output >>= 9;

    // 36 db
    lTemp = ( pole6.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole5 , lTemp2 , A32 , B32 )
    ProcessLP( pole6 , pole5.lastout , A32 , B32 )

    output = pole6.lastout * ( 128 + reso );
    output *= 9;
    output >>= 10;
    }

    //------------------------------------------------------------------------------
    // Handle LowPass Filter 24 db
    //------------------------------------------------------------------------------
    void HandleLP24()
    {
    A32 = ( 32768 - B32 ) >> 1;

    // 12 db
    lTemp = ( pole2.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole1 , lTemp2 , A32 , B32 )
    ProcessLP( pole2 , pole1.lastout , A32 , B32 )

    output = pole2.lastout * ( 128 + reso );
    output *= 3;
    output >>= 8;

    // 24 db
    lTemp = ( pole4.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole3 , lTemp2 , A32 , B32 )
    ProcessLP( pole4 , pole3.lastout , A32 , B32 )

    output = pole4.lastout * ( 128 + reso );
    output *= 3;
    output >>= 8;
    }

    //------------------------------------------------------------------------------
    // Handle LowPass Filter 12 db
    //------------------------------------------------------------------------------
    void HandleLP12()
    {
    A32 = ( 32768 - B32 ) >> 1;

    // 12 db
    lTemp = ( pole2.lastout * reso ) >> 6;
    lTemp2 = output - lTemp;

    ProcessLP( pole1 , lTemp2 , A32 , B32 )
    ProcessLP( pole2 , pole1.lastout , A32 , B32 )

    output = pole2.lastout * ( 128 + reso );
    output *= 3;
    output >>= 8;
    }

    #2
    JanJansen
    Super Member
    • Total Posts : 530
    • Reward points : 0
    • Joined: 2012/08/25 03:26:34
    • Location: 0
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/13 08:50:38 (permalink)
    0

    //------------------------------------------------------------------------------
    // init audio
    //------------------------------------------------------------------------------
    void initaudio()
    {
    A32 = B32 = 0;

    ResetFilter( pole1 );
    ResetFilter( pole2 );
    ResetFilter( pole3 );
    ResetFilter( pole4 );
    ResetFilter( pole5 );
    ResetFilter( pole6 );

    HandleFilter = HandleLP36;
    }

    //------------------------------------------------------------------------------
    // filter
    //------------------------------------------------------------------------------
    B32 = coefB[ frequency ];

    HandleFilter();

    // lookuptable coefficients based on this code multiplyd by unsigned short 32768
    /*
    fB = float( atan( ( Pi64 * freq ) / fSampleRate ) );
    fB = -( fB - 1.0f ) / ( 1.0f + fB );
    fA = 0.5f * ( 1.0f - fB ); // done in code, no need for table
    */

    // higpass code ( i dont get good results with this in integers )
    /*
    fA = 0.5f * ( 1.0f + fB );
    */

     
    #3
    Nikolay_Po
    Super Member
    • Total Posts : 1884
    • Reward points : 0
    • Joined: 2012/04/01 13:49:27
    • Location: Russia, Novorossiysk
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/14 02:56:14 (permalink)
    3 (1)
    I see nothing incorrect on the waveforms. Good sound, though! Good results!
    The resonance at the bottom is due to the slope of the signal. The signal goes high at low angle. Very few high frequency energy is generated due to low rise speed. So there is no overshooting.
    Your filter is "casual" "causal", it can't predict. That is why it can't create an overshoot when the signal suddenly changes the direction at the top of your wave.
    Then signal goes vertically down. A lot of high frequency energy is created. This is a cause of an overshoot.
    Different slopes, different overshoot. Asymmetric signal, asymmetric overshoot/ringing. All is correct.
     
    Good luck!
    post edited by Nikolay_Po - 2017/07/14 03:00:12
    #4
    Nikolay_Po
    Super Member
    • Total Posts : 1884
    • Reward points : 0
    • Joined: 2012/04/01 13:49:27
    • Location: Russia, Novorossiysk
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/14 03:02:33 (permalink)
    0
    Also, if it is possible to introduce filter delay, you may build non-causal filter with the same (or similar) AFC. This way the overshoot may become quite symmetric.
    #5
    JanJansen
    Super Member
    • Total Posts : 530
    • Reward points : 0
    • Joined: 2012/08/25 03:26:34
    • Location: 0
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/14 08:22:16 (permalink)
    3 (1)
    Thanks Nikolay,
    i dont wanto have delayed response.
    i also heard of zero delay filters, i have to check it out sometime.
     
    I,m sure the resonance should show up also on the higher part, because with a square wave it has the same problem.
    Maybe i can post a movie tomorrow again with the square wave.
     
    I found a small typo in the code :
    For 24 db filter it should have the volume like the 36db on the 24db part :

    output *= 5;
    output >>= 9;

     
    I also made a small improvement in the 36db :

    output = pole6.lastout * ( 128 + reso * 2 );

    post edited by JanJansen - 2017/07/14 08:24:56
    #6
    Nikolay_Po
    Super Member
    • Total Posts : 1884
    • Reward points : 0
    • Joined: 2012/04/01 13:49:27
    • Location: Russia, Novorossiysk
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/14 10:59:08 (permalink)
    3 (1)
    I believe the ringing will be at the end of the transition but not at the begin. It is normal. Faster transient - higher ringing.
    #7
    JanJansen
    Super Member
    • Total Posts : 530
    • Reward points : 0
    • Joined: 2012/08/25 03:26:34
    • Location: 0
    • Status: offline
    Re: 36 db resonant IIR filter needs adjustment 2017/07/15 06:44:53 (permalink)
    0
    You are right Nikolay, i tested with square wave, all good now.
     
    Only with the highpass i still have problems, the resonance goes at a high frequency.
     

    //------------------------------------------------------------------------------
    #define ProcessHP( p , in , a , b ) \
    lTemp = in; \
    lTemp -= p.lastin; \
    lTemp *= a; \
    lTemp >>= 15; \
    \
    lTemp2 = p.lastout; \
    lTemp2 *= b; \
    lTemp2 >>= 15; \
    \
    p.lastout = lTemp + lTemp2; \
    p.lastin = in; \
    //------------------------------------------------------------------------------
    A32 = ( 32768 + B32 ) >> 1;

     
    I made it different by substracting the lowpass from the input, only that cost more CPU,
    why is the resonance at high frequency with the original highpass code ?
     
    I also would like to know how to make this filter self resonating.
    And how do i change the sound of the filter, coefficient B only sets the frequency.
    #8
    Jump to:
    © 2019 APG vNext Commercial Version 4.5