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

Add fadeout #217

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Add fadeout #217

wants to merge 1 commit into from

Conversation

mathstuf
Copy link
Contributor

No description provided.

src/source/fadeout.rs Outdated Show resolved Hide resolved
@danjl1100 danjl1100 mentioned this pull request Sep 2, 2019
@mathstuf
Copy link
Contributor Author

Updated. Now pins volume to 0. when the fadeout time has expired.

@OvermindDL1
Copy link

A fadeout seems exceptionally situation specific rather then generic.

Why not instead have something that just does standard audio envelope manipulation? I.E. it would be defined with an attack, a decay, a sustain, and a release in that order. When applied to a known-length source the attack adjust the beginning of it, trivial to do a fade-in (as well as more complex things), the decay then is the transition from the end of the attack to the sustain, the sustain is then the 'settled on' volume or other adjustments (this should work on a lot more than just volume depending on the callback passed in of course), then the release can either be done right before it ends, or potentially right after (to extend it, which is more traditional but both are often supported).

Fade-out and fade-in would both be trivially and efficiently built on that without requiring a specialized multitude of structs for each and every potential sound manipulation that could be done via normal audio envelope's. For example, a fade-out would just be a release (or some step before it, prerelease perhaps? would only work on sources with known lengths though all the others would work on sources with unknown lengths) with the rest set to 0 times and no-ops as is traditional. The code would execute just as efficiently and it would give significant power. You can then define fadein/fadeout functions on sinks as wrappers to the envelope (as well as a full envelope function, as well as other common envelope effects).

@mathstuf
Copy link
Contributor Author

That seems beyond my knowledge of audio manipulation (in that I know what those words mean in general, but not in this context). As long as a method for fading out that takes a Duration exists (possibly with some Ramp::Linear argument for a little bit more fanciness, but even that seems a bit much for something that many other audio libraries also just have a simple duration parameter for), I'm OK with it. To that end, when such an API does exist, the implementation of this method can then call that API. But, I don't think it's something I would feel confident implementing at this time.

If you really want to go far, something built on splines seems possible as well and isn't restricted to a trapezoid shape (just going on my intuition here).

@OvermindDL1
Copy link

OvermindDL1 commented Oct 25, 2019

@mathstuf Actually it's all really simple things, much more so then most people think. I'd recommend going through this audio tutorial when you get a half hour or hour or so, it's all in-browser but teaches what they are and how they work. The envelope section is directly related here but adding all the traditional audio effects would be very useful: https://learningsynths.ableton.com/

Envelopes aren't fancy enough to use splines either (though it would make for more capabilities). ^.^

@mathstuf
Copy link
Contributor Author

Finally got some time to go back and look at this :) . So looking at that, I think that's slightly different. Are you suggesting to have a source which applies some envelope to another source? That seems a bit different here where we don't know how long sustain is since the fadeout portion is triggered by an external event. I think another envelope source modifier makes sense (maybe this can then be rebased on top of that, but without linear types enforcing the attack to decay to sustain to release flow, the API feels like its going to be unweildy.

I also have no use case for such features, so I don't want to sink more time into it.

@dyc3
Copy link

dyc3 commented Jul 30, 2020

I can clearly see the advantage of having an envelope based source, but I think it should be a separate source. The fade in/out sources should stay because they are easy to use (if anything, refactored to work on top of the envelope source).

Any chance we can get this merged in? I have a project that needs this feature badly.

@mathstuf
Copy link
Contributor Author

mathstuf commented Sep 9, 2020

My main use case is to fade out a looping piece of music at the end of a level. I suppose you could compute the length of the audio doing something like:

if let Some(duration) = source.total_duration() {
    let source = source.fadeout(fade_out_duration);
    source.periodic_access(duration - fade_out_duration, |s| s.start())
} else {
    // Probably Box<Source> to align with the above.
}

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.

4 participants