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

Change mix calculation on audiodelays.Echo to allow full range. #9994

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

relic-se
Copy link

In the current implementation of the audiodelays.Echo.mix parameter, the source audio sample is first combined with the echo sample and then mixed again with the source audio sample using the value of mix parameter. This effectively only allows you to control the level of the effect audio and not the level of the source audio (see the following graph, red=source, blue=effect).

image

In this update, I've extended the range of the mix parameter to allow you to isolate the effect audio from the source while still being able to achieve the original mixing range between 0.0 and 0.5 (see the following graph, red=source, blue=effect).

image

In my use-case, I am using CircuitPython to calculate a delay effect on an incoming signal and then mix the output using the analog pathways of my audio codec. To achieve the maximum effect, I want the digital signal to be fully "wet" (ie: mix=1.0) and then I can rely on the "dry" signal controlled by the codec.

@gamblor21
Copy link
Member

Just to make sure I understand correctly, the idea is at 0.5 both the original and effect play at full (1.0) volume, as opposed to at 0.5 they both play at 0.5 volume?

From the graphs above it seems we lose the ability to go say 70% original 30% effect? That was the original intention of the mix parameter.

I'm not familiar enough with how other synths do this so just wondering. @todbot any thoughts if you have a moment as you originally gave me the idea?

@relic-se
Copy link
Author

Just to make sure I understand correctly, the idea is at 0.5 both the original and effect play at full (1.0) volume, as opposed to at 0.5 they both play at 0.5 volume?

Because the original sample is combined with the echo sample right from the get-go, it isn't possible to get both the effect and the sample at 50% volume (without an audiomixer, see comments below about levels).

word = echo + sample_word;

The current algorithm is essentially the following:

output = sample * (1 - mix) + (echo + sample) * mix

This can be expanded and simplified down to the following:

output = sample - sample * mix + echo * mix + sample * mix = sample + echo * mix

Essentially, you're only able to control the level of the echo and not the original source (see first graph from the top post).

From the graphs above it seems we lose the ability to go say 70% original 30% effect? That was the original intention of the mix parameter.

I don't believe you're technically able to achieve a 70/30 mix with the current release. It would be more like 100/30 (mix=0.3). The only way you'd be able to get 70/30 exactly is by using an audiomixer.MixerVoice on the output. This would require mix=0.4286 (0.3/0.7) and level=0.7. With this update, it would essentially be the same by the mix would be half, 0.2143.

Note: I think there might be a slight misunderstanding as to what "effect" means for audiodelays.Echo. I'm interpreting the "effect" as the echoed response to the original sample impulse and not the combination of that response and the sample.

Overall, I think the "mixing" paradigm needs to be implemented differently depending on the audio effect in question. For instance, audiofilters.Filter uses a more direct mixing algorithm which I think is appropriate for that effect (see the following graph, red=source, blue=effect, green=red + blue aka volume).

image

@relic-se relic-se marked this pull request as draft January 27, 2025 15:44
@relic-se relic-se marked this pull request as ready for review January 27, 2025 20:33
@dhalbert dhalbert requested review from jepler and gamblor21 January 28, 2025 20:47
Copy link
Member

@jepler jepler left a comment

Choose a reason for hiding this comment

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

The documentation of the mix parameter is not super clear to me. Please check it over with an eye to whether it needs to be revised with this change, and whether it could be clearer.

shared-bindings/audiodelays/Echo.c Outdated Show resolved Hide resolved
@relic-se
Copy link
Author

The documentation of the mix parameter is not super clear to me. Please check it over with an eye to whether it needs to be revised with this change, and whether it could be clearer.

The documentation of mix was actually fairly close. I've just added the expected result of 0.5 as to better represent the new implementation.

I noticed the description of decay was different between the constructor and the property. I found the constructor to better represent that property, so I updated the property docstring to match.

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.

3 participants