Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Filter Tracking with Resonance issue

  1. #1
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    182

    Filter Tracking with Resonance issue

    Hallo friends

    I'm using the Teensy Audio Lib for a state variable filter. I control the filter frequency for key tracking via the frequency control input.

    The filter's corner frequency is set via filter.frequency()

    The control of the filter frequency works correctly. But the resonance frequency shifts downwards and no longer matches the filter frequency.

    I programmed the Filter.octave control to a fixed value of 7 (7 octaves).



    Code:
    //*************************************************************************
    // play Voices
    //*************************************************************************
    void voice1On(byte note, byte velocity, float level) {
      keytrackingValue = KEYTRACKINGAMT[note] * keytrackingAmount;  // keytrackingAmount = 0.0 - 1.0  (0-100%)
      filterModMixer1.gain(2, keytrackingValue); 
      voices[0].note = note;
      voices[0].timeOn = millis();
      // Amp velocity
      float velo = (0.5 - myAmpVelocity) + (VELOCITY[velocitySens][velocity] * myAmpVelocity);
      voiceMixer1.gain(0, velo);
      //voiceMixer1.gain(0, VELOCITY[velocitySens][velocity] * VOICEMIXERLEVEL);
      // Filter velocity
      velo = ((0.5 - myFilVelocity) + (VELOCITY[velocitySens][velocity] * myFilVelocity));
      //FilterVelo1.amplitude(velo);
      filterEnvelope1.noteOn();
      ampEnvelope1.noteOn();
      voices[0].voiceOn = 1;
      if (glideSpeed > 0 && note != prevNote) {
        glide1.amplitude((prevNote - note) * DIV24);   //Set glide to previous note frequency (limited to 1 octave max)
        glide1.amplitude(0, glideSpeed * GLIDEFACTOR); //Glide to current note
      }
      if (unison == 0)prevNote = note;
    }
    
    
      filterOctave = 7.0f;
      filter1.octaveControl(filterOctave);
      filter2.octaveControl(filterOctave);
      filter3.octaveControl(filterOctave);
      filter4.octaveControl(filterOctave);
      filter5.octaveControl(filterOctave);
      filter6.octaveControl(filterOctave);
      filter7.octaveControl(filterOctave);
      filter8.octaveControl(filterOctave);
    
    void updateFilterFreq() {
      filter1.frequency(filterFreq);
      filter2.frequency(filterFreq);
      filter3.frequency(filterFreq);
      filter4.frequency(filterFreq);
      filter5.frequency(filterFreq);
      filter6.frequency(filterFreq);
      filter7.frequency(filterFreq);
      filter8.frequency(filterFreq);
    }
      
      filterOctave = 7.0f;
      filter1.octaveControl(filterOctave);
      filter2.octaveControl(filterOctave);
      filter3.octaveControl(filterOctave);
      filter4.octaveControl(filterOctave);
      filter5.octaveControl(filterOctave);
      filter6.octaveControl(filterOctave);
      filter7.octaveControl(filterOctave);
      filter8.octaveControl(filterOctave);
    
    // KeyTracking Amt
    const static float KEYTRACKINGAMT[128] = {
        0, 0.008, 0.016, 0.024, 0.031,
        0.039, 0.047, 0.055, 0.063, 0.071, 0.079, 0.087, 0.094, 0.102, 0.110,
        0.118, 0.126, 0.134, 0.142, 0.150, 0.157, 0.165, 0.173, 0.181, 0.189,
        0.197, 0.205, 0.213, 0.220, 0.228, 0.236, 0.244, 0.252, 0.260, 0.268,
        0.276, 0.283, 0.291, 0.299, 0.307, 0.315, 0.323, 0.331, 0.339, 0.346,
        0.354, 0.362, 0.370, 0.378, 0.386, 0.394, 0.402, 0.409, 0.417, 0.425,
        0.433, 0.441, 0.449, 0.457, 0.465, 0.472, 0.480, 0.488, 0.496, 0.504,
        0.512, 0.520, 0.528, 0.535, 0.543, 0.551, 0.559, 0.567, 0.575, 0.583,
        0.591, 0.598, 0.606, 0.614, 0.622, 0.630, 0.638, 0.646, 0.654, 0.661,
        0.669, 0.677, 0.685, 0.693, 0.701, 0.709, 0.717, 0.724, 0.732, 0.740,
        0.748, 0.756, 0.764, 0.772, 0.780, 0.787, 0.795, 0.803, 0.811, 0.819,
        0.827, 0.835, 0.843, 0.850, 0.858, 0.866, 0.874, 0.882, 0.890, 0.898,
        0.906, 0.913, 0.921, 0.929, 0.937, 0.945, 0.953, 0.961, 0.969, 0.976,
        0.984, 0.992, 1
    };



    Thanks for help. Greetings Rolf

  2. #2
    Senior Member
    Join Date
    Apr 2019
    Posts
    144
    You need to set filterOctave lower (1.0f) and it'll track properly. This is why my code has this odd feature where filterOctave is changed with cut off freq, to maintain deep basses at low cut off and better sharper, resonance at higher cut off. This is how TSynth gets sub-bass and percussive sounds, because the resonance peak is wider.

    Code:
            float filterOctave = 0.0;
            //Altering filterOctave to give more cutoff width for deeper bass, but sharper cutoff at higher frequencies
            if (value <= 2000) {
                filterOctave = 4.0f + ((2000.0f - value) / 710.0f);//More bass
            } else if (value > 2000 && value <= 3500) {
                filterOctave = 3.0f + ((3500.0f - value) / 1500.0f);//Sharper cutoff
            } else if (value > 3500 && value <= 7000) {
                filterOctave = 2.0f + ((7000.0f - value) / 4000.0f);//Sharper cutoff
            } else {
                filterOctave = 1.0f + ((12000.0f - value) / 5100.0f);//Sharper cutoff
            }

  3. #3
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    182
    The calculation must work according to this formula.

    Signal is Filter.tracking value. For frequence shift with 1.octav is signal value 0.14285 (7 octaves)

    Click image for larger version. 

Name:	Tracking.jpg 
Views:	2 
Size:	20.3 KB 
ID:	24783

    I can't find that in your code.

  4. #4
    Senior Member
    Join Date
    Apr 2019
    Posts
    144
    It's in here: https://github.com/PaulStoffregen/Au...ter_variable.h

    Perhaps you're misunderstanding what filterOctave does? And I am too? Perhaps someone can explain, I though it was to do with width of the cutoff freq, although that should be 12dB?!?

  5. #5
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    182
    I want to control the filter tracking over seven octaves with midi notes.

    These are the keytracking values (Signal) for the FilterModMixer input.




    Greetings Rolf

  6. #6
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    182
    In the TSynth the key tracking is monophonic. I made it polyphonic in the Voices


    polyphone KeyTracking
    Code:
    //*************************************************************************
    // play Voices
    //*************************************************************************
      void voice1On(byte note, byte velocity, float level) {
      keytrackingValue = KEYTRACKINGAMT[note] * keytrackingAmount;
      filterModMixer1.gain(2, keytrackingValue); 
      voices[0].note = note;
      voices[0].timeOn = millis();
      filterEnvelope1.noteOn();
      ampEnvelope1.noteOn();
      voices[0].voiceOn = 1;
      if (glideSpeed > 0 && note != prevNote) {
        glide1.amplitude((prevNote - note) * DIV24);   //Set glide to previous note frequency (limited to 1 octave max)
        glide1.amplitude(0, glideSpeed * GLIDEFACTOR); //Glide to current note
      }
      if (unison == 0)prevNote = note;
    }

  7. #7
    Senior Member Rolfdegen's Avatar
    Join Date
    Sep 2020
    Location
    Germany
    Posts
    182
    This is the table for the filter tracking values. The middle frequency is 440Hz.

    The filter corner frequency and resonance is shifted 100% with keytracking.

    Code:
    const static float KEYTRACKINGAMT[128] = {
        
        -0.53571551f, -0.52380850f, -0.51190530f, -0.49999932f, -0.48809746f, -0.47618825f, -0.46428706f, -0.45238275f,
        -0.44047653f, -0.42857142f, -0.41666832f, -0.40476328f, -0.39285837f, -0.38095136f, -0.36904815f, -0.35714218f, 
        -0.34523781f, -0.33333346f, -0.32142769f, -0.30952351f, -0.29761939f, -0.28571428f, -0.27380941f, -0.26190447f,
        -0.24999965f, -0.23809570f, -0.22619101f, -0.21428636f, -0.20238067f, -0.19047632f, -0.17857166f, -0.16666637f,
        -0.15476225f, -0.14285714f, -0.13095227f, -0.11904732f, -0.10714251f, -0.09523782f, -0.08333317f, -0.07142856f,
        -0.05952353f, -0.04761918f, -0.03571452f, -0.02380975f, -0.01190461f,  0.00000000f,  0.01190486f,  0.02380939f,
         0.03571423f,  0.04761895f,  0.05952397f,  0.07142858f,  0.08333329f,  0.09523795f,  0.10714290f,  0.11904765f,
         0.13095228f,  0.14285714f,  0.15476201f,  0.16666674f,  0.17857137f,  0.19047627f,  0.20238093f,  0.21428572f,
         0.22619044f,  0.23809524f,  0.25000004f,  0.26190479f,  0.27380954f,  0.28571428f,  0.29761904f,  0.30952378f,
         0.32142861f,  0.33333332f,  0.34523808f,  0.35714286f,  0.36904758f,  0.38095239f,  0.39285711f,  0.40476187f,
         0.41666669f,  0.42857142f,  0.44047618f,  0.45238093f,  0.46428571f,  0.47619047f,  0.48809522f,  0.50000001f,
         0.51190476f,  0.52380953f,  0.53571429f,  0.54761904f,  0.55952380f,  0.57142857f,  0.58333332f,  0.59523809f,
         0.60714285f,  0.61904761f,  0.63095239f,  0.64285713f,  0.65476190f,  0.66666665f,  0.67857143f,  0.69047619f,
         0.70238094f,  0.71428571f,  0.72619047f,  0.73809524f,  0.74999999f
    Code:
    //*************************************************************************
    // play Voices
    //*************************************************************************
      void voice1On(byte note, byte velocity, float level) {
      keytrackingValue = KEYTRACKINGAMT[note] * keytrackingAmount;   // keytrackingAmount is 0.0 - 1.0 (0-100%)
      filterModMixer1.gain(2, keytrackingValue); 
      voices[0].note = note;
      voices[0].timeOn = millis();
      float velo = (0.5 - myAmpVelocity) + (VELOCITY[velocitySens][velocity] * myAmpVelocity);
      voiceMixer1.gain(0, velo);
      velo = ((0.5 - myFilVelocity) + (VELOCITY[velocitySens][velocity] * myFilVelocity));
      filterModMixer1.gain(3, velo); 
      filterEnvelope1.noteOn();
      ampEnvelope1.noteOn();
      voices[0].voiceOn = 1;
      if (glideSpeed > 0 && note != prevNote) {
        glide1.amplitude((prevNote - note) * DIV24);   //Set glide to previous note frequency (limited to 1 octave max)
        glide1.amplitude(0, glideSpeed * GLIDEFACTOR); //Glide to current note
      }
      if (unison == 0)prevNote = note;
    }
    
    
    void voice2On(byte note, byte velocity, float level) {
      keytrackingValue = KEYTRACKINGAMT[note] * keytrackingAmount;
    Greetings from germany. Rolf

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •