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

How to use existing processors with stereo or multichannel audio feeds? #417

Closed
generalelectrix opened this issue Sep 28, 2022 · 4 comments
Labels
enhancement New feature or request question Further information is requested

Comments

@generalelectrix
Copy link

generalelectrix commented Sep 28, 2022

Hello, and thanks in advance for this whole vast library! Lots of useful things in here, and I'm having a lot of fun integrating a few of them into my project.

I'm a bit confused how to use tools like EnvelopeFollowerProcessor and FilterProcessor with audio streams with more than one channel. Since both of them contain internal state, it seems like I need to instantiate one instance of each of them per-channel. I'm not sure how to elegantly wire this up, though. This is especially confusing due to this section of code in the implementation of FilterProcessor:

fn s_process_frame(&mut self, frame: &mut [SampleType]) {
let input = frame[0];
let output = self.filter.state.process1(
&self.filter.coefficients,
input,
self.filter.denormal_prevention.alternating_current(),
);
for value in frame {
*value = output;
}
}

It appears that for each frame, we only use the 0th channel as input, and then overwrite the result of the filter operation onto all other channels in the frame, essentially ignoring the other input channels and producing identical output on all channels. Am I missing something here?

@yamadapc
Copy link
Owner

yamadapc commented Sep 29, 2022

Hey 👋 . These are indeed mono since you need to make a decision on how to handle multi-channel input. However you're right that looks a bit fishy 😅.

You should use the let out: f32 = filter.s_process(sample); method to process a single Float sample for both of them, but I'll patch this processor so it has a sensible s_process override (since at the moment it does not), instead of only implementing s_process_frame.

@generalelectrix
Copy link
Author

Thanks for the reply! I went the route of allocating a processor per channel and then calling them in my own impl of s_process_frame which seems to work well.

Given that this whole project is a big experiment I'm certainly not expecting any major changes, but it might be worth considering splitting the single-sample vs multi-channel methods out into two separate traits. That might make it easier to ensure you don't accidentally call the default method impl from the SimpleAudioProcessor trait for one or the other case that is unimplemented for a processor, or for cases like these stateful processors that fundamentally cannot process more than one audio channel.

Regardless, thanks again for your work on this library, it made implementing some audio reactivity in a lighting art project very straightforward.

@yamadapc
Copy link
Owner

yamadapc commented Oct 3, 2022

Thanks for your feedback! I'll try to incorporate that. I'm glad it was helpful in some way.

@yamadapc yamadapc added enhancement New feature or request question Further information is requested labels Oct 6, 2022
@yamadapc
Copy link
Owner

yamadapc commented Oct 6, 2022

I'm going to close this and use #440. Thanks for the suggestions and feedback!

@yamadapc yamadapc closed this as completed Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants