Skip to content

Conversation

fonsargo
Copy link
Contributor

Here is a new AGC (Auto Gain Control) effect for Mixxx. AGC automatically adjusts the gain of an audio signal to maintain a consistent output level.

I couldn't find an existing issue or feature request for this, but I had a prototype from last year when I was working on the compressor effect. So I thought it would be great to turn it into a proper effect as well. It's based on the compressor effect, but with different gain calculations.

Feel free to share any suggestions or ideas for improvement!

@github-actions github-actions bot added the build label Apr 15, 2025
@ronso0 ronso0 removed the build label Apr 15, 2025
@bigboipete
Copy link

@fonsargo Just from the PR description, to me it looks like the same Replay Gain does. What's the difference between Replay Gain and your goal?

@fonsargo
Copy link
Contributor Author

@fonsargo Just from the PR description, to me it looks like the same Replay Gain does. What's the difference between Replay Gain and your goal?

The difference is very big, because AGC dynamically adjusts the gain of a signal every second or even millisecond, while ReplayGain just calculates the average audio volume and add/subtract the constant amount of gain for the whole track. You can try it using my MR and you will hear the difference (choose some track with big amplitude, the good example is Adele - Skyfall. You can barely hear anything in the beginning, but it's quite loud in the middle).

@bigboipete
Copy link

So, it's similar to an Auto Make-up Gain of a compressor but without the additional compression, right?

@fonsargo
Copy link
Contributor Author

No, it's not similar. Auto make up adjusts gain, so the output level is as close as possible to the input level. It's useful when you want to compress audio, but do not want to change the amplitude of the whole track (in my example with Adele - Skyfall the begging will still be quiet and the middle will still be loud after compression).
However AGC adjusts the gain regardless the input level: it always tries to keep the target volume. But you're right that the AGC doesn't compress the audio.

@fonsargo
Copy link
Contributor Author

fonsargo commented Jul 7, 2025

Just a friendly reminder if someone can take a look on this, please.

@JoergAtGithub
Copy link
Member

Could you please merge the main branch in, to trigger CI.

@github-actions github-actions bot added the build label Jul 8, 2025
Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

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

LGTM otherwise

Copy link
Member

@Swiftb0y Swiftb0y left a comment

Choose a reason for hiding this comment

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

haven't tested this locally yet, but code LGTM. Waiting for @JoergAtGithub

Comment on lines +14 to +15
double calculateBallistics(double paramMs, const mixxx::EngineParameters& engineParameters) {
return exp(-1000.0 / (paramMs * engineParameters.sampleRate()));
Copy link
Member

Choose a reason for hiding this comment

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

If I were pedantic, this should also just take std::chrono::milliseconds and cast to double internally, but that really doesn't matter. In theory you could create your own double-based chrono milliseconds using std::chrono::duration<std::milli, double>, but thats just a neat trick and not necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason why I didn't use milliseconds is that attack and release could be fractional, for example fast attack could be 0.05ms. Also it comes from attack and release knob, which returns double: m_pAttack->value(). I didn't consider creating my own double-based chrono ms, but I'm not sure that will increase readability to be honest :)

Copy link
Member

Choose a reason for hiding this comment

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

yeah, it probably wouldn't improve readability, just make it less likely to accidentally assign unrelated quantities/units to each other.

@JoergAtGithub
Copy link
Member

LGTM! Thank you for this new builtin effect!

@JoergAtGithub JoergAtGithub merged commit f66a5e8 into mixxxdj:main Aug 16, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants