This uses a bit more memory (each voice needs to hold buffers for the
deinterleaved samples of each channel, instead of just one buffer for the
current channel being mixed on the device), but it will allow for handling
formats that need or prefer their channels decoded together.
NULL devices are still checked, but invalid non-NULL device handles will invoke
undefined behavior, as will attempting to close the device while the function
is being executed (modifying the device state while the function is being
called was inadvertently already UB, and will now remain so).
This change is solely so alcRenderSamplesSOFT can be used in a buffer callback,
and other places that need functions to be real-time safe. The verification
requires locking to access the device list, which isn't allowed in a real-time
callback.
It will not be called while the device is running. If the first call succeeds,
a subsequent call that happens to fail must leave the existing device state as
it was so it can be resumed.
This is a rough first pass. It will fail when trying to re-open the same device
which can only be opened once (for instance, with direct hardware access, on
hardware that doesn't do its own mixing). Some backends won't guarantee the new
device is usable until the reset() or start() call.
This is mostly for the SampleConverter, used by some capture backends. When
recording at really low rates, like 5512hz, with a device capturing at a higher
rate like 44100hz or 48000hz, it hits the filter's downscaling limit and
produces pure silence.
In such cases, it's better to just accept some aliasing noise so that the app
will still get some recognizable audio. The alternative would be to scale the
desired rate by 2x, 3x, etc until it's above the bsinc limit, then take every
2nd, 3rd, etc sample of the result as if by an extra simpler resampler pass.
Port names seem to be structured as <device_name:channel_name> or
<app_name:channel_name>. I'm not sure if this is always the case, but it seems
some other apps expect something like this.
Also fix the port selection to exclude MIDI ports and allow non-physical ports.
Voices that stop and have no more accessible samples now fade out over 64
samples max. The extra loaded samples are also prevented from moving away from
0 amplitude. Paused voices that still have samples will still fade out over the
whole mix.