Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sound worsening with each sample rate increment. #15

Open
RafaGago opened this issue Jul 13, 2021 · 12 comments
Open

Sound worsening with each sample rate increment. #15

RafaGago opened this issue Jul 13, 2021 · 12 comments

Comments

@RafaGago
Copy link

I've developed MixMaxtrix, a kind-of mixer and multifx. It is up for KVR Developer Contest 2021. One the FX I bundle is a functionally equivalent port of Chow Phaser (credited and with the original name, of course).
https://www.kvraudio.com/product/mixmaxtrix-by-artv

Now when adding a brute force oversampler to some of the FX I noticed that the sound worsens on ChowPhaser instead of improving. It changes a lot in a non-subtle way.

I tried with your original ChowPhaser v1.1.1 (on Reaper Linux if that matters) by changing sample rate from 44100 to 176400. It happens too, so it seems that it is not an issue of my port.

Playing a drum loop with hihats.
ChowPhaserMono settings that make it obvious:
Depth: 0.86
Freq: 8.76
Skew: -1
Feedback: 0.79
Modulation: 0.54
Stages: 33.48
Drive: 4
Trash: 4.34
Dirt: 4.58

With these settings the difference between 44100 and 176000 is substatial (4x). It worsens more at 16x.

Unfortunately I can almost nothing about DSP and my math is extremely rusty. I haven't made the effort to understand the code in full but I wasn't able to find a simple fix.

@RafaGago
Copy link
Author

Playing a bit more, it seems like this might be a problem feedback section, specially with the "trash" stage.

@jatinchowdhury18
Copy link
Owner

Thanks for reporting this! On one level, it does make sense since the nonlinear behaviour controlled by the "thrash" parameter is somewhat dependent on the sample rate. I'll investigate a bit more and see if I can figure out a way to correct for it so that at least it doesn't sound worse as the sample rate increases.

Thanks,
Jatin

@jatinchowdhury18
Copy link
Owner

I'm playing around with adding a sample rate "correction" factor for the thrash parameter. You can see the change here. To my ears it sounds a bit better at higher sample rates with no change at lower sample rates, but I'd love a second opinion.

@RafaGago
Copy link
Author

RafaGago commented Jul 15, 2021

I tested on my port and it didn't make a lot of difference at 16x. Notice that the Drive/d1 parameter also shows the side effect to a certain extent. D3 doesn't.

I tried compiling the commit you passed, but it is requiring jack to be installed and I had to leave. I'll try to check later.

@RafaGago
Copy link
Author

It reproduces in your code. I played the same drum loop and these settings:

Depth: 0.74
Freq: 8.71
Skew:-1.06
Feedback: 0.79
Mod: 0.54
Stages: 33.48
Drive: 0.1
Trash: 5
Dirt: 0.1

At 44100 I adjust for a 0dB peak. At 176k the level peaks at +5dB. Although the settings are nonsense, at 44100 it sounds like a phaser, at 176k it sounds like stuttering.

@jatinchowdhury18
Copy link
Owner

Ah okay, thanks for sharing your settings again. I think I'm seeing what the problem is now. Basically, the configuration of the nonlinearities is causing a DC build-up somewhere in the feedback filter structure, that only seems to triggered at higher sample rates The way the DC build-up interacts with the nonlinearities is what's causing the "stuttering" type of sound. With that in mind, I've got a few things to try:

  • Remove the nonlinearities, and make sure the DC build-up isn't being caused by something "upstream" from the feedback filter.
  • Try tweaking nonlinearities to remove any DC build-up that they are causing directly. I have a decent idea of how this might work, but it might be tricky to do it in a way that keeps the filter sounding the same as it does now at the same settings.
  • Try adding a DC blocker in the filter's feedback path. I don't love this option since it would add a little bit of group delay to the feedback path, but if it's only enabled at higher sampling rates, it might not make a difference.

Anyway, I'll keep investigating this weekend, and let you know what I find!

Thanks,
Jatin

@RafaGago
Copy link
Author

RafaGago commented Jul 17, 2021

That makes sense.

Maybe I will say something foolish, because all I know is just by tweaking and reading sources of what other people do, KVR, etc. I have no formal education on DSP. Unrelated, but thanks for making your code open source, I'd never have understood ADAA reading directly from the papers.

Coming back to the topic, if the DC blocker phase response has actually a bad effect on the sound (this is a phaser after all, so there is no need for phase preservation), maybe there is a way to put a matched allpass filter correcting/minimizing the phase response of the DC blocker just afterwards, then a fractional delay line to round to a sample boundary.

If this block amounts to 1 sample delay, then the feedback timing would be the same-ish (the correction might not be perfect) at 44100 and 88200 and keep improving from there. The bandwith would still be higher at higher SR, of course.

There is also the possibility that the DC blocker improves the sound at base rate. If the sound changes are very minimal at non-extreme settings maybe it's worth to go for it.

@jatinchowdhury18
Copy link
Owner

Sorry, I ended up being super busy this weekend, and wasn't able to make much progress. I'll try to dig into it further today and tomorrow.

Coming back to the topic, if the DC blocker phase response has actually a bad effect on the sound (this is a phaser after all, so there is no need for phase preservation), maybe there is a way to put a matched allpass filter correcting/minimizing the phase response of the DC blocker just afterwards, then a fractional delay line to round to a sample boundary.

This is definitely a good idea, but might require further correction elsewhere in the filter. The main reason I'm worried about the DC blocker in the feedback path is that the delay it would add to the signal would actually alter the cutoff frequency of the filter. Adding the matched allpass filter like you mentioned should make the added delay close to an integer number of samples. So for example, if we could make the DC blocker + matched allpass have a total delay of 1 sample, then I could add a sample delay to all the other delayed paths in the filter, and then design the filter coefficients at half the sample rate. That said, I'm hoping there will be a simpler solution than that!

There is also the possibility that the DC blocker improves the sound at base rate. If the sound changes are very minimal at non-extreme settings maybe it's worth to go for it.

Absolutely :)!

@jatinchowdhury18
Copy link
Owner

Okay, so I've made a few more changes on the nl-samplerate branch. Basically adding the DC blocker (turns out it doesn't have much effect on the phase/frequency response of the overall filter), and tweaking the range of the "Dirt" parameter. It does change the sound of the effect a little bit, but I think I like it a little better. That said, definitely needs some more testing and tweaking.

@RafaGago
Copy link
Author

Cool, I'll try tomorrow

@RafaGago
Copy link
Author

There is an improvement. Now I'd say that it feels like a phaser. With this setting on a drum loop containing hi hats at 176k:

Depth: 0.95
Frequency: 2.6
Skew: 0.6
FeedBack: 0.95
Modulation: 1
Stages: 47
Drive 0.1
Trash: 0.1
Dirt: 0.1

With this "extreme" setting Drive/Trash/Dirt can be tested independently.

Dirt is acceptable. Trash and to a lesser degree Drive still make the treble to sound painful with a lot of transients. Maybe the top octaves can be removed/smeared on the FB loop (?). Maybe the more frequent feedback causes more aliasing and that is what we hear? It would be nice to try a 2/4 pole butterworth LP on the feedback loop cutting around 5kHz?.

@RafaGago
Copy link
Author

RafaGago commented Aug 23, 2021

Using 3 of the DC blockers named by "mystran" on the thread below and double precision seems to make things much better, even at 16x.

https://www.kvraudio.com/forum/viewtopic.php?f=33&t=545280#top

One after each tanh call.

auto prev_lp_out = states[onepole::z1];
onepole::tick (coeffs, states, in);
return in - prev_lp_out;

The problem it changes the sound a lot on higher sample rates. Enough to be called a new plugin. The "trash" control becomes brutal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants