flibitijibibo / flibitBounties

Pile of programming bounties for things flibit can't do right now
27 stars 0 forks source link

Implement low/high/band-pass filters for FAudio #3

Closed flibitijibibo closed 6 years ago

flibitijibibo commented 6 years ago

Introductory Information:

XAudio2 is Microsoft's mostly-low-level library for game audio programming. Among its features is the ability to add filtering effects to source/submix voices.

FAudio is FNA's upcoming replacement for the Audio subsystem. It was originally designed as just an XACT reimplementation, but was eventually expanded to act as an DirectX Audio implementation with support for XAudio2, XACT3, X3DAudio, and XAPO. The repository is currently here.

The Project:

FAudio needs a filtering system that allows for low/high/band-pass filters to be applied both directly on a voice's output samples as well as on each voice's output sends during the mixing stage. In the API this is applied via the SetFilterParameters and SetOutputFilterParameters functions, respectively.

The filter applied by SetFilterParameters is set after resampling and before mixing, and the filters applied by SetOutputFilterParameters are set during the final mix to each output send. Note that there are only three parameters we have to worry about: the filter type, the cutoff frequency, and the Q factor, all of which are detailed in the documentation for XAUDIO2_FILTER_PARAMETERS.

This will probably be implemented via a series of static functions in FAudio_internal.c with some filter state data allocated for each stage where filtering can occur. (You can Ctrl+F "filters" and see a couple places where the filter would be applied.)

For now we only care about low/high/band-pass filters; the other filter types listed in XAUDIO2_FILTER_TYPE are NOT required. Additionally, you only need to worry about integrating your filter functions into the SetFilterParameters stage; the SetOutputFilterParameters stage is NOT required.

Prerequisites:

FAudio is written in C99, so you'll need to be reasonably comfortable with that language to finish this project. Experience with digital signal processing is a plus, and strong math skills will also be helpful.

You will probably also want to look at Microsoft's own write-ups of the XAudio2 filtering feature.

Example Games:

XACT games use this pretty often for low-pass filtering, though FNA added a couple secret "extensions-by-reflection" to add filtering support to the SoundEffect API. Examples of both use cases include FEZ, Apotheon, Cryptark, Bastion, and Charlie Murder.

How Much Can flibit Help?

I am reasonably familiar with how filters work at a high level, but that's about it. Other than XAudio2 spec stuff you're probably on your own with this one.

Budget/Timeline:

Measuring in weekends, I expect this to take about 1 weekend. It'll probably take an afternoon to read up on Microsoft's filtering API and implementation with the rest of the time coming up with a filtering function and data structure to plug into FAudio. I currently have $500 USD allocated for this project.

flibitijibibo commented 6 years ago

This bounty has been updated to reduce the scope slightly; you now only need to worry about the SetFilterParameters implementation for now. This is because only the source voice caches are deinterleaved and writing an interleaving filter function would probably be very annoying and unpleasant, and the filter functions should work once we fix the interleaving problem even after they're finished.

flibitijibibo commented 6 years ago

This bounty has been updated once again; as it turns out the XAudio2 spec specifically states that sample data is stored in an interleaved format when sent to signal processors...

https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.ixapo.ixapo.process(v=vs.85).aspx

... so unfortunately part of the filter function will include an int channels parameter to loop through each channel with its own filter state. I don't think it'll do much more than that (we already needed per-channel filter states anyway), but it is kind of annoying to have that extra loop.

flibitijibibo commented 6 years ago

This is now being worked on! Will try to update as this develops.

flibitijibibo commented 6 years ago

This has been completed by @JohanSmet! That marks the first completed flibitBounty!