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

Simpler power/envelope follower #384

Merged
merged 9 commits into from
Aug 27, 2020

Conversation

paulfd
Copy link
Member

@paulfd paulfd commented Aug 20, 2020

This one is much cheaper and should do the job well enough for what we use it for.

@paulfd paulfd requested a review from jpcima August 20, 2020 00:28
@jpcima
Copy link
Collaborator

jpcima commented Aug 20, 2020

Ok I would like to suggest a bit more

  • since we don't apparently need to analyze level of distinct channels, may we do a single analysis of stereo-linked input?
    (take in the sum of left and right channels absolute values, cf. gate/compressor stlink)
  • may we buffer the frames using a fixed-size analysis window?

smoothedChannelEnvelopes[i] =
channelEnvelopeFilters[i].tickLowpass(std::abs(input[s]));
const float meanPower = sfz::meanSquared(input);
meanChannelPowers[i] = meanChannelPowers[i] * (1 - factor) + meanPower * factor;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The analysis signal is not windowed at the input.
In former experience, RMS value of raw input can be very imprecise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some indication or the power btw, it does not need to be too precise.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I would once find the measurement to be very noisy, (this was another project out of sfizz)
and the curve next to unusable.
Imo, at the first look, I'm not feeling convinced by this method.
It's tied to the samples per block. If the signal is too low frequency, and the block size is short, the method seems likely to fail.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's supposed to be somewhat independent on the samples per block, the factor changes depending on the expected block size and the actual one. I will double check since I did this at 2 in the morning.

I don't see how windowing would help though, it will bias the average? The noisiness can be smoothed away, the issue being that attacks and releases are not tracked quickly enough. Apparently people also take the max of 2 parallel filters for such cases, with different responses, to track attacks fast and releases less so.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's supposed to be somewhat independent on the samples per block, the factor changes depending on the expected block size and the actual one. I will double check since I did this at 2 in the morning.

Disregard, as it stands you're right it's not independent since I had a no-op multiplication in the normalizations

@paulfd
Copy link
Member Author

paulfd commented Aug 20, 2020

Ok I would like to suggest a bit more

* since we don't apparently need to analyze level of distinct channels, may we do a single analysis of stereo-linked input?
  (take in the sum of left and right channels absolute values, cf. gate/compressor `stlink`)

Good point.

* may we buffer the frames using a fixed-size analysis window?

Won't this be expensive if we do it for each voice?

@paulfd
Copy link
Member Author

paulfd commented Aug 21, 2020

This implements the same thing, except I had a useless normalization by the maximum block size. I also put the combined filters for release and attacks. The test files are organ ranks (cuz I had them right here); "Plein jeux" is a relatively high-frequency mixture, "Bourdon 16" is a very low frequency quasi-pure sine wave, and "Doublette 2" is a very high frequency rank.

There

It is not block-size independent indeed. I'll try to tweak it further, in the end I'd just like a minimum bias compared to sample-by-sample.

@paulfd
Copy link
Member Author

paulfd commented Aug 24, 2020

I added a small correction to the coefficient calculation based on the assumption that:

  1. The power for each sample in the block is the same as the mean power of the block ;
  2. The coefficient per-sample is small

The results are there. It does not meaningfully improve or change the behavior of the envelope follower. I also tried to go deeper in the Taylor expansions for the block version but also there it does not seem to impact the algorithm positively. I suspect most of the bias stems from assumption 1, which appears a bit unavoidable if we want simpler per-block version for the follower. I'm tempted to label this "good enough for the purpose", what do you think?

I wonder also if #353 could just disable the envelope follower in the voices if the voice stealing algorithm does not use it?

@jpcima jpcima force-pushed the simpler-envelope-follower branch from 73a9384 to 298befa Compare August 27, 2020 07:41
@jpcima
Copy link
Collaborator

jpcima commented Aug 27, 2020

It's made independent of block size. It's replaced with a fixed block size which is set in config.
Performance is unaffected, and result is looking OK at first.
Check it, merge if you want.

@paulfd
Copy link
Member Author

paulfd commented Aug 27, 2020

The memory cost is a bit higher but I'm OK with this solution. Note that it will still be indirectly dependent on sample rate, but as I said, I don't think it's a big issue given the current use we make of this. Thanks for the improvements 🙂

@paulfd paulfd merged commit 81169b8 into sfztools:develop Aug 27, 2020
@paulfd paulfd deleted the simpler-envelope-follower branch August 27, 2020 15:03
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

Successfully merging this pull request may close these issues.

2 participants