COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 01-06-2021, 02:45 PM   #1
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 340
Default Filter modulation frequency scaling

I feel like this should be straightforward but I’m not getting my head around it! I have a filter and a bipolar LFO. I want the LFO to modulate the cutoff frequency in a way that scales to the cutoff frequency, as it modulates much more deeply when the cutoff is at lower frequencies.

I think I need to translate the LFO modulation, but I’m getting a bit confused with power functions etc.

My LFO is ranging from -1 to 1 and the filter cutoff from 0 to 1. I can translate these to frequency values and back again.

I'd post my code, but it's a mess from trying things out!
Bobflip is offline   Reply With Quote
Old 01-06-2021, 03:04 PM   #2
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,187
Default

I guess you will want to something like y = 2^x, where x is your LFO. If x is in [-1, 1], then y would be in [0.5, 2]. You can scale x to get a smaller range, e.g. 2^(x/2) would give you y in [0.707, 1.41], etc.
Tale is offline   Reply With Quote
Old 01-06-2021, 04:04 PM   #3
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 340
Default

Thanks for your reply! Had brought y = 2^x into it, but still hit the problem that adding the LFO to a low cutoff value results in more modulation than adding it to a higher cutoff value. Also means that the LFO depth knob has more effect when the cutoff is low. Feels like I'm missing an important step of the puzzle!
Bobflip is offline   Reply With Quote
Old 01-06-2021, 04:39 PM   #4
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 340
Default

This is what I have so far. Oversampling is implemented in my plugin but it's not active while I'm working on this. Will be optimising after the functionality is sorted.

Code:
    
    // Process the input signal
    for (int i=0; i<numchans; i++)
    {
        // Get the sample to process
        double sampleBeingProcessed = inputs[i][s];
        
        // Filter
        if (GetParam(kFilterActive)->Value())
        {
            frequency = GetParam(kFilterCutoff)->Value() / oversampledsamplerate;
            double resonance = GetParam(kFilterResonance)->Value();
            inputFilter[i]->setQ(resonance);
            
            lfotempval = LFODataGeneratedA[i][s];
            lfotempval = pow(2.0, lfotempval)-1;
            lfotempval = lfotempval * (GetParam(kFilterCutoffLFO1Mod)->Value() * 0.001);
            
            inputFilter[i]->setFc(frequency+lfotempval);

            filtered = inputFilter[i]->process(inputs[i][s]);
            sampleBeingProcessed = filtered;
        }
    }

Last edited by Bobflip; 01-06-2021 at 04:46 PM.
Bobflip is offline   Reply With Quote
Old 01-06-2021, 04:59 PM   #5
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 340
Default

Got it! Multiplied the translated LFO value with the cutoff frequency, then added that to the cutoff frequency and divided the result by the sample rate to bring it to between 0 and 1. Seems to be correct so far anyway...

Code:
     // Process the input signal
     for (int i=0; i<numchans; i++)
     {
         // Get the sample to process
         double sampleBeingProcessed = inputs[i][s];
         
         // Filter
         if (GetParam(kFilterActive)->Value())
         {
             frequency = GetParam(kFilterCutoff)->Value() / (oversampledsamplerate);
             double resonance = GetParam(kFilterResonance)->Value();
             inputFilter[i]->setQ(resonance);
             
             lfotempval = LFODataGeneratedA[i][s];
             lfotempval = pow(2.0, lfotempval)-1;
             lfotempval = lfotempval * (GetParam(kFilterCutoffLFO1Mod)->Value() * 0.01);
             
             convfreq = GetParam(kFilterCutoff)->Value() + (GetParam(kFilterCutoff)->Value()*lfotempval);
             
             inputFilter[i]->setFc(convfreq / oversampledsamplerate);

             filtered = inputFilter[i]->process(inputs[i][s]);
             sampleBeingProcessed = filtered;
         }
Bobflip is offline   Reply With Quote
Old 01-06-2021, 05:15 PM   #6
stw
Human being with feelings
 
stw's Avatar
 
Join Date: Apr 2012
Posts: 277
Default

Quote:
Originally Posted by Bobflip View Post
This is what I have so far. Oversampling is implemented in my plugin but it's not active while I'm working on this. Will be optimising after the functionality is sorted.
How is you kFilterCutoff param shaped? I guess it provides an exponential curve (shape > 1)? The most straight forward approach would be to shape your lfo the same way.
To keep things simple remove the shape from your knob and do the exponential scaling after summing your cf sources. Something like...
convfreq = pow(BOUNDED((lfotempval + knob), 0, 1), shape)
stw is offline   Reply With Quote
Old 01-06-2021, 05:46 PM   #7
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 340
Default

It's linear, and the LFO is also sent to other parameters which don't want exponential scaling. I added the bounding in after the last post, but will try out your suggestion too.
Bobflip is offline   Reply With Quote
Old 01-07-2021, 12:49 AM   #8
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,187
Default

I see you've figured it out already, but FWIW: The idea was to multiply your freq with y, so x in [-1, 1] would result in [freq*0.5, freq*2].
Tale is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 09:04 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.