kcat / openal-soft

OpenAL Soft is a software implementation of the OpenAL 3D audio API.
Other
2.15k stars 522 forks source link

[Question] Idea of splitting the output channel; is this possible in the current API? #996

Open hypatia-of-sva opened 3 months ago

hypatia-of-sva commented 3 months ago

Hello kcat,

I was thinking about the following idea of implementing an analog rumble signal: I could simply do the normal AL calculations, but with buffers that contain very low frequency noises outside the hearable spectrum for the "rumble sources", and then take the output of AL and split it up by frequency, and play back the hearable spectrum, but process the other part with a different algorithm.

Is there a possiblity to do that cross platform? Can I use the output of AL, do something to it, and then play it back with the native sound device? I don't really see it in the extensions, but it could be it's lost in one of the enum options I maybe don't exactly understand.

In any way, if it's not there, I would be interested to know if this would be relatively easy to implement or a very complicated thing to do; it might look easy to me (as it might just be one FFT over the AL output, a split and a reverse FFT), but that might be the mathematician talking over enginerring things they don't understand, so I would like to know if I'm totally off on this or if this would be something that could be possible, or maybe even is already possible with a bit of wrapping code.

With regards, Hypatia of Sva.

kcat commented 3 months ago

The ALC_SOFT_loopback extension allows mixing audio to your own buffer, to do with what you want. You're responsible for outputting it to be heard, though. Either using a second OpenAL device with a single source, or a different audio API.

Be aware that using an FFT to split the audio like you want won't be easy, and likely have a fair bit of latency. Simply taking the FFT, reading and removing low frequencies, then reversing it back to samples, will result in aliasing issues. Each processed chunk won't properly follow from each other since, from the perspective of the FFT, the samples in a given chunk are their own self-contained looping signal, which they aren't in reality. There are ways around the issue using overlapping windows, but that requires a fair amount of extra samples before you can start getting output from the input. FFTs also have length restrictions, you need specific numbers of samples to calculate an FFT with, which may not align with the number of samples you need to output at a given time, requiring more buffering. The size of the FFT will also influence how precise your frequency measurements are, with fewer samples resulting in wider frequency bands (so the lowest frequency band may cover both inaudible and audible low frequencies; basically sample_rate / sample_count will give the range in hz covered by each frequency band in the FFT).

There's also no telling what low-frequency sounds may end up in the audio mix. Even if you carefully author and use specific sounds that you know don't have inaudibly low frequencies where they're not supposed to, various processes like resampling, pitch shifting, and even gain ramping can introduce noise, potentially resulting in ultra low frequencies being detected where they're not supposed to be.