-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Effect unit mixing mode #1676
Effect unit mixing mode #1676
Conversation
Another fun chain to play with in D+W mode: Bitcrusher -> Moog Filter -> Autopan. Turn up the Resonance on the Moog Filter and play with the LPF. |
ae6a008
to
df34782
Compare
It turns out that a dry/wet parameter is needed for the Reverb effect. Before now the effect was always fully wet with no dry, with the amount of the effect control with the Send parameter. However, when the effect unit is in dry + wet mode, the Send parameter is not as useful because it reduces the volume of the whole chain. In this mode, it is more useful to keep Send fully up and adjust Dry/Wet. However, when the effect unit is in D/W mode, Send is better to use to adjust the amount of the effect because lowering it smoothly fades out the effect. Admittedly it is odd to have both parameters, however I think this is the best we can do until @kshitij98 implements parameter hiding and rearrangement. I have updated the parameter tooltips to clarify their use cases. To test this I recommend playing with the chain BQ EQ -> Echo -> Reverb. |
88d78fe
to
e4f179e
Compare
Anyone care to review? @ronso0, @ferranpujolcamins? |
I'm short on time, sorry. |
Oh, interesting idea. I think that would help because it's not an on/off switch. |
so Echo and Reverb do not add the dry signal to their output in "Send" mode
Using the Send parameter when the effect unit is in D+W mode does not work as desired because it reduces the volume of the whole effect unit.
e4f179e
to
fd25553
Compare
"BQ EQ -> Echo. Turn the Low parameter knob of the BQ EQ effect (not the normal deck EQ) all the way down (left) and turn the Send knob for the Echo effect all the way up (right). Enable both effects and turn up the effect unit mix knob. In D/W mode, you will hear that the bass is taken out of the track" - This is referred to as being a high pass echo. |
Yes, but that single use case doesn't help name this new mode. |
This simply isn't true! The amount of frequencies lost from the original is the same on each and is almost definitely due to phase issues of mixing filtered/EQ'd sound back in with the original and is one of the largest issues in digital eq/crossover design. The main difference which is clearly audible is the fact that the effected signal can be much louder without having lost any level from the original as there is not the constant power mixing mode of the wet/dry knob. This is even more evident if you use the Moog Filter instead of the EQ and only put the effect on the very top end of the frequency range. IMPO this would be better resolved by having a way to make up the gain from the effect chain. Whether this would be a user controlled knob or an Automatic Gain Compensation button (to make effects level to dry level) I'm not sure, although I'd lean towards the AGC method as it would work better for keeping the level consistent when playing with controls such as Feedback or Resonance. If you don't believe me load in some 20Hz-20kHz ramps, actually record the output and do some real measurements. |
Yes, that is the purpose of this PR. The question is what to call the two different modes.
I don't understand how this is relevant. Keeping a consistent level would not be desirable. When I use an Echo effect, I don't want the unechoed signal to get quieter. |
Ahh sorry, from your description I thought you meant something weird was going on as you said you lose more bass from one method than the other, which you don't.
The unechoed signal would never get affected by this!! You're not doing anything to the dry signal, only the wet signal at the end of the entire effect chain. Wat makes you think the unechoed dry signal would be effected in any way? Having a gain knob for the effects chain before the chain wet/dry mix wouldn't do that to the wet echoed signal either. Which is what I assume you were actually trying to say.... Even with AGC you would want a release phase of a couple of seconds or more (seen up to around five seconds used) to prevent any abrupt level changes which would sound horrible and almost no echo effect is going to be long enough to adversely affect that with the correct settings. But as always there would be niche cases. Button as it's optional you don't even have to have it turned on in the first place..... With your method it's still very easy to create effects chains working on only small frequency range which even with D+W mode are barely audible and it would be a larger fix across the board to make it so no matter the output of the effects chain due to filtering etc you can still have it at a level where it can be reasonably mixed in with the original dry signal and clearly heard at output. This is not the achieved by just adding in a different summing more for the wet dry knob! |
But for what it is I think your D/W and D+W labelling on the skins is perfect. In the manuals you could say something along the lines of: |
I don't know what you mean. Did you turn the Send parameter of the Echo effect all the way up? The Send knob acts like a volume fader for the whole effect chain in D+W mode. It can only make the output of the effect unit quieter, not louder. I will edit the parameter tooltip to explain this.
Great, I'll go ahead and implement the button for other skins then. In the code, I'll call the modes DrySlashWet and DryPlusWet to match the GUI and rename the EffectChainInsertionType enum to EffectChainMixMode. |
For documentation, I think some language like this could help: "Use D/W mode if you want EQ and filter effects to change the sound of the track. Use D+W mode if you want EQ and filter effects to only change the effected signal." |
Sorry if I offended @Be-ing, I do agree there is good use case for these modes. But the issues you describe it as fixing don't exist as you have described them. I didn't think I could hear it as explained when initially testing on your request the other day and so when I had free time yesterday I did a null test of the normalised output of the two modes and proved categorically that there is no difference in the frequencies of the output of the two methods with comparable wet mix knob levels (although there is, of course, an obvious level difference.) As it seems clear that despite the opening statements of the thread that you do fully understand this I apologise. I was worried you were trying to fix something that wasn't faulty in the way you thought and didn't want you wasting your time if that was the case. |
@kazakore what do you think of adding the Dry/Wet parameter to the Reverb effect? Do the parameter tooltips adequately explain the differences between Send and Dry/Wet (you'll need tooltips turned on in the Interface preferences to see them). |
You're right, it does need some clarification that for effecting the track in entirety (IE all wet at output) you need D/W mode and mentioning that this would be normal operation for EQ, Filter and Compression is a good idea. Using the filtered echo as the example for the other mode seems good too. |
Yes, after @kshitij98 implements effect chain presets, I want to include some default presets in Mixxx. One of those would be BQ EQ -> Echo -> Reverb in D+W mode. |
Slightly off topic but as I've noticed them while testing this PR I will comment on it here, hope that's OK: Flanger and Phaser are both fairly similar effects, with very similar controls. The names of these controls could quite well be standardised across the two effects a bit more. I also get a little GUI bug (Tango). Any effects loaded after having started Mixxx which have buttons (Quantize/Triplets) the text on the button is not visible unless the button is enabled on loading the effect into the chain. It's fine on the other skins as they don't use two colour text inside the button. Also changing skins to test that and the skin appears to load at smallest possible size and I have to hit F11 a few times to resize and get the skin actually working. Think I saw this (or similar) reported against another branch on Zulip the other day |
Okay, thank you for the feedback @kazakore. I am going to merge this now so @kshitij98 can start refactoring EffectChain/EffectChainSlot without creating merge conflicts with this branch. I will follow up this PR soon to add the new button to other skins. |
I think this branch has not received a code review yet, right? |
Sorry, you are right. It would have been better for @kshitij98 to start working from this branch and wait to merge this until it could have been reviewed more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I have added some comments. @Be-ing will you issue them post merge?
@@ -434,7 +434,7 @@ Descriptor<PlateX2>::setup() | |||
|
|||
// (timrae) we have our left / right samples interleaved in the same array, so use slightly modified version of PlateX2::cycle | |||
void MixxxPlateX2::processBuffer(const sample_t* in, sample_t* out, const uint frames, const sample_t bandwidthParam, | |||
const sample_t decayParam, const sample_t dampingParam, const sample_t blendParam) { | |||
const sample_t decayParam, const sample_t dampingParam, const sample_t blendParam, double wet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please break long lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"double wet" is misleading, because is is not the wet signal, it is the mixParam or the dryWetParam.
all other parameters are reduced to sample_t precision we should do the same for this parameter too.
@@ -224,7 +224,7 @@ class PlateX2 | |||
class MixxxPlateX2 : public PlateStub { | |||
public: | |||
void processBuffer(const sample_t* in, sample_t* out, const uint frames, const sample_t bandwidthParam, | |||
const sample_t decayParam, const sample_t dampingParam, const sample_t blendParam); | |||
const sample_t decayParam, const sample_t dampingParam, const sample_t blendParam, double wet); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break long lines.
@@ -82,7 +82,8 @@ EffectManifestPointer EchoEffect::getManifest() { | |||
send->setName(QObject::tr("Send")); | |||
send->setShortName(QObject::tr("Send")); | |||
send->setDescription(QObject::tr( | |||
"How much of the signal to send into the delay buffer")); | |||
"How much of the signal to send into the delay buffer\n" | |||
"When the effect unit is in D+W mode, keep this turned up all the way")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment does not makes sense. You can produce the same effect using the send and D+W knob and we have actually the meta knob mapped as default. So the user can use it as usual independent from the mix mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you actually tried this? The Send parameter acts as a volume knob for the whole chain in D+W mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is the essence of a send knob in a return Mixxx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, so the only use case for the Send parameter in this mode is to smoothly fade the effect out. It cannot be used to adjust the level of the Echo relative to the rest of the chain as it behaves in D/W mode. I see now that the wording of this tooltip may imply that the user should never use the Send parameter in D+W mode even in the case of smoothly fading out the effect, so I'll clarify that: "When the effect unit is in D+W mode, keep this turned up all the way unless fading the effect out"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this the original use case for this?
How about: "Note: In D+W mode the output of the delay buffer is the only input of the following effect."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be better to fully explain how the effect behaves in each mode:
"In D/W mode, the dry signal is passed through.
In D+W mode, only the echoed signal is output, so adjusting this parameter adjusts the volume of the whole chain."
// The number of insertion types. Also used to represent "unknown". | ||
Num_Insertion_Types | ||
enum class EffectChainMixMode { | ||
DrySlashWet = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Crossover" Or "DryWetCrossover"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A crossover is a device that splits a full spectrum audio signal into different frequency bands for different amplifiers or speaker drivers. I do not think it makes sense to use that word here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment what it actually means.
Num_Insertion_Types | ||
enum class EffectChainMixMode { | ||
DrySlashWet = 0, | ||
DryPlusWet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"AddWetToDry"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the terms in the code should match the GUI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, But in that case add a comment here what it actually means.
@@ -221,19 +225,19 @@ void EchoEffect::processChannel(const ChannelHandle& handle, EchoGroupState* pGr | |||
if (gs.ping_pong < delay_samples / 2) { | |||
// Left sample plus a fraction of the right sample, normalized | |||
// by 1 + fraction. | |||
pOutput[i] = pInput[i] + | |||
pOutput[i] = (addDry ? pInput[i] : 0) + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these inner conditionals will likely detroy CPU pipelinig. It is better to move it out and duplicate some code for speed here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay
"How much of the signal to send in to the effect\n" | ||
"Lowering this fades out the effect smoothly\n" | ||
"Use this to adjust the amount of the effect when the effect unit is in D/W mode\n" | ||
"When the effect unit is in D+W mode, keep this turned up all the way")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same here, the advice does not fit to the metaknob mapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no mechanism to magically switch the metaknob linking with the mix mode, nor do I think there should be. I think the best way to improve the UX with the Send and Dry/Wet parameters of this effect will be to include default effect chain presets with Mixxx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just remove the advise here. The Rest is OK. The meta knob mapping still works as desired even in D+W mode.
@@ -454,7 +454,8 @@ void MixxxPlateX2::processBuffer(const sample_t* in, sample_t* out, const uint f | |||
sample_t mono_sample = blend * (in[i] + in[i + 1]) / 2; | |||
sample_t xl, xr; | |||
PlateStub::process(mono_sample, decay, &xl, &xr); | |||
out[i] = xl + in[i]; | |||
out[i + 1] = xr + in[i + 1]; | |||
out[i] = (xl * wet) + (in[i] * (1 - wet)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We loose the original reverb sound now. if we set wet to 0.5, we have the original sound but with -6 dB.
@@ -73,14 +76,31 @@ EffectManifestPointer ReverbEffect::getManifest() { | |||
send->setMinimum(0); | |||
send->setDefault(0); | |||
send->setMaximum(1); | |||
|
|||
EffectManifestParameterPointer dryWet = pManifest->addParameter(); | |||
dryWet->setId("dry_wet"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the use-case of this parameter? Can't we follow the echo implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turns out that a dry/wet parameter is needed for the Reverb effect. Before now the effect Was always fully wet with no dry, with the amount of the effect control with the Send parameter.
No,It was always "out[i] = xl + in[i];"
The dry_wet knob makes it worse, now and is redundant with the Mix knob.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To test this I recommend playing with the chain BQ EQ -> Echo -> Reverb.
You can argue the same for the revers order, but the Echo has no Dry/Wet Knob.
I think this is a case that musically does not make much sense, compared to the GUI clutter.
We should stick with one concept. If it is really a desired effect, my preferred solution is to put it in a dedicated new effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All return effects like echo and reverb, do there effect by taking the dry signal, alter it and put it back, on top of the dry channel. If we chain a echo, and put the reverb into the delay path, it has no access to the dry signal and cannot work as return effect any more. Musically it might may sense to add it as insert effect here. In this case the reverb has to pass through the delayed signal as 100% and adds the reverb onto it. This can be controlled by the send button, and might be additional controlled by a mix knob at the output.
The same is true if you put the reverb first. I don't know if it makes sense to put an echo after but if the echo eats all non delayed signal, the reverb effect is gone.
So it looks like that the effect mode must only be consumed from one effect in the chain to allow the most desired effect without overcomplicate the GUI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No,It was always "out[i] = xl + in[i];"
Whoops, you are right. I think I got confused because the Echo effect's Send parameter acts as a redundant volume knob for the whole chain in D+W mode, but with Reverb mixed as out[i] = xl + in[i]
that is not the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I think we can simply remove the new Dry/Wet parameter for Reverb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
We need to decide if we need something else.
Should reverb follow the mix mode like echo? Is there a use case to add a filter to the reverb wet path?
If yes, I think only the first effect in the chain should switch to return mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking back at the diff of the commit where I introduced the new Dry/Wet parameter, I got confused because I had changed
out[i] = xl + in[i];
to
out[i] = xl + (addDry ? in[i] : 0);
in 2b72491 when I introduced the effect unit mix mode. That made it so the Send parameter of Reverb did act as a redundant volume knob of the whole chain in D+W mode. However, I didn't need to do anything to Reverb in 2b72491. Simply keeping out[i] = xl + in[i];
with the Send parameter controlling the input regardless of the effect unit mix mode as it was before works.
dryWet->setDescription(QObject::tr( | ||
"Mix between the input (dry) and output (wet) of the effect\n" | ||
"Lowering this fades out the effect abruptly\n" | ||
"Use this to adjust the amount of the effect when the effect unit is in D+W mode")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the Mix knob not sufficient for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The effect unit mix knob affects the whole chain.
Effect unit mixing mode
Pass the "insertion type" of effect units to effects so the Echo and Reverb effects adjust their output appropriately. I have added a button to the Tango skin, tentatively labelling the two modes "D/W" (dry/wet) and "D+W" (dry+wet). D/W is the default, familiar behavior where Echo and Reverb mix their input with their output. In D+W mode, those effects do not add their input to their output, and the effect unit mix knob adds the wet signal on top of the unmodified dry signal. This allows for chaining effects such that they only change the signals of other effects in the chain without modifying the original track, which allows for frequency-selective effects
A good way to hear the difference is by loading BQ EQ -> Echo. Turn the Low parameter knob of the BQ EQ effect (not the normal deck EQ) all the way down (left) and turn the Send knob for the Echo effect all the way up (right). Enable both effects and turn up the effect unit mix knob. In D/W mode, you will hear that the bass is taken out of the track. In D+W mode, the middle and high frequencies will be echoed and the bass of the track will still be there.
The big questions are what to call these two modes and how to represent them with a button. Please suggest some ideas.
Implementing https://bugs.launchpad.net/mixxx/+bug/1662049
This is implemented on top of the LV2 branch to ensure it doesn't create any merge conflicts with that branch.