SynthMaker

Implementing sample rate change to a filter

Archive · 2006 17 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

Kingston ·

Hi,

I'm baffled here, I'm trying to make a plugin to work correctly on all samplerates, but I ran into a problem. Let's use the basic SM moog filter as an example:

streamin in; streamin cutoff; streamin res; streamout out; float out1,out2,out3,out4; float in1,in2,in3,in4; float cutoff,f,fb,f2,input;

input=in; f=cutoff*1.16; f2=f*f; fb=res*(1.0-0.15*f2); input=input-out4*fb; input=input*0.35013*f2*f2; out1 = input+0.3*in1+(1-f)*out1; in1=input; out2=out1+0.3*in2+(1-f)*out2; in2=out1; out3=out2+0.3*in3+(1-f)*out3; in3=out2; out4=out3+0.3*in4+(1-f)*out4; in4=out3; out=out4;

How do I get it to behave correctly when the samplerate is something different to 44.1kHz?

I was using the timing info block to send the samplerate(fs) to the filter,but my implementation didn't work and I scrapped it.

What do I need to modify to make filter sound the same on all samplerates?

Cheers.

Michael

MyCo ·

AFAIK, you have nothing to change, since a filter works from zero to the half of the samplingrate. So you only need to change your GUI-Display. just display Samplerate * cutoff / 2... that's the cutoff frequence

for cutoff = 0.5 at sample rate 44.1kHz it is 11025Hz and at 22.02kHz it is 5512.5Hz

Kingston ·

Something's not quite right still,

have a look at this:

streamin in; streamin cutoffo; streamin res; streamout out; streamin fs; float out1,out2,out3,out4; float in1,in2,in3,in4; float cutoff,f,fb,f2,input;

cutoff=cutoffo*(44100/fs);

input=in; f=cutoff*1.16; f2=f*f; fb=res*(1.0-0.15*f2); input=input-out4*fb; input=input*0.35013*f2*f2; out1 = input+0.3*in1+(1-f)*out1; in1=input; out2=out1+0.3*in2+(1-f)*out2; in2=out1; out3=out2+0.3*in3+(1-f)*out3; in3=out2; out4=out3+0.3*in4+(1-f)*out4; in4=out3; out=out4;

is the cutoff=cutoffo*(44100/fs); part totally wrong?

I'm trying to keep the filter sounding the same on all samplerates using that. What am I doing wrong?

MyCo ·

The filter code part is totaly samplerate independent. Use the input to the filter as a value from 0..1 and if you want to display the cutoff frequency in Hz use the formula: cutoffHz = cutoff * samplerate / 2

Kingston ·

I'm sorry but the filter code is totally samplerate dependent. (I can hear it!)

basically I need to make the filter code aware of the samplerate changes, and compensate the cutoff accordingly.

By the way, this particular filters frequency values work between 0-1.

which means 1=FS, I think.

I figured out how to deal with it now. The answer is in the second code version I posted. But your answer confused me quite a bit.

I wish I could get a better confirmation on this, anyone?

[edit]

works like a charm with the code above! 🙂

oddson ·

That works, but you're doing that calculation over and over at sample rate.

I think it would be better to feed it into the code with a green calculation instead.

Also, you don't have to limit the numerator to 44.1KHz - whatever value you put in there becomes twice the max cutoff frequency, if you're feeding a 0-1 control value.

Kingston ·

Haha. stupid me. I had your exact implementation for the first revision of the workaround. Somehow I thought it would be more efficient on the code block.

A brainfart!

[fixed]

Ta!

MyCo ·

To the thing from oddson: If your host runs at 11kHz you get a value from 0 to 4 as cutoff frequency. The filter won't work. Also you could hear the difference between the samplerates, because the response-curve is for 11kHz. Which meens if your cutoff is at 11kHz, the filter won't work.

I'll post a version, that shows the way I explained it.

MyCo ·

so, here it is: http://music-drive.com/filter_ex.osm

infuzion ·

Kingston wrote: Haha. stupid me. I had your exact implementation for the first revision of the workaround. Somehow I thought it would be more efficient on the code block.

It would be if the input values constantly changes, eg hooked up to an OSC rather than BPM info. Green data doesn't send info unless it somthing down link changes, so it's better with somewhat static values.

oddson ·

infuzion wrote: It would be if the input values constantly changes, eg hooked up to an OSC rather than BPM info. Green data doesn't send info unless it somthing down link changes, so it's better with somewhat static values.

You can still use a [source rate] modulated control - that's why I've shown a stream multiplier in my example (you could use a float multiply if you only had it conected to a green control).

I hope I'm not misunderstanding what you're saying...

Kingston ·

MyCo wrote: so, here it is: http://music-drive.com/filter_ex.osm

I understand what you're saying, but that's bad practise in general.

Just simply cannot have a preset enabled plugin where presets will sound different depending on samplerates. 😮

The users would hate that and complain as soon as they found out about such non-standard behaviour.

Thanks for reminding me about the lower than 44.1khz support. It's relatively easy to implement to my current scheme. (basically just setting parameter max to 1.)

Kingston ·

infuzion wrote: Green data doesn't send info unless it somthing down link changes, so it's better with somewhat static values.

yeah, I understood the difference. My control data is completely green and all conversions, weighting etc. are done before the final "de-zipper to DSP".

Kingston ·

Just to add further,

things like GUI display and conversion for the parameters visible to the user should be completely separate from the DSP related variables and ranges.

In this example, the gui would always display the same thing. no matter what the samplerate. Only DSP itself would be samplerate compensated, something invisible to the user..

stefan ·

Rescale input frequency so that it is "samplerate independant'", then limit it to the highest frequency the filter can handle (usually nyquist).

Example

Cutoff in hz: 10.000 in normalized freq, at 44khz: 10.000/22050 (divide with nyquist) in normalized freq, at 11khz: 10.000/5512 which is more than 1.0, and hence, higher then nyquist. limit to 1.0 when input freq is higher than 1.

This method will only alter the percieved cutoff frequency when it is above nyquist.

Everyone with me? 🙂

Kingston ·

Well that's even better than just setting the parameter max to 1. 😀

Although one could safely assume that setting the reference range to 44.1 would be ok, and users of lower samplerates would just have to see "dead space" in the knob where it doesn't affect anything. Unless the actual filter code itself was upsampled, or similar in the first place.

oddson ·

And if anyone still cares, here's MyCo's convertion example done with this scheme...

[url=http://members.shaw.ca/oddson/filtersandsr.osm]

OSM[/url]

N.B.: The Sample Rate Tester is to allow you to check the calculations without changing your sample rate - of course it will mess up the actual control value if you have it set to anything other than 'actual' or the correct value.

[sorry if anyone's been trying this file... must have had a typo in the URL]

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.