This crackling was happening due to abrupt volume transitions as the
gain changes for each channel as sounds move around the world. This
change smooths out these transitions using linear interpolation.
* Sounds can now have another node be used as input rather than a
data source.
* Sounds can now have a configurable input and output channel count.
For sounds that are backed by a data source, the input channel
count will always be set to the data source's native channel count.
* Sounds can now be initially attached to any node and input bus
rather than only a sound group.
With this change, sounds can now be used as groups. In future commits,
it's likely that ma_sound_group will be unified with ma_sound. Whether
or not the `ma_sound_group_*()` APIs will continue to exists is for now
undecided.
This change allows more flexibility for doing custom effects before the
spatialization stage in the DSP pipeline. The problem with the existing
design is that there's no way to apply a custom effect before
spatialization which becomes a problem because spatialization will
often increase the channel count which results in excessive effect
processing due to the increased channel count. Now it should be
possible to set up a graph such that an effect can be plugged in
between the data source and the spatializer.
A new function called `ma_sound_init_ex()` has been added which is what
needs to be used to initialize a sound without a data source. This API
uses the config/init pattern. The config is called `ma_sound_config`.
When the listener is looking at exactly the same direction as the world
up vector the 3D math breaks down due to a cross product evaluating to
a zero length vector.
This fixes the following APIs:
* ma_calculate_buffer_size_in_milliseconds_from_frames()
* ma_calculate_buffer_size_in_frames_from_milliseconds()
Public issue https://github.com/mackron/miniaudio/issues/283
The range of the value isn't obvious to any compiler, as it could go for
one iteration or 4 billion iterations. Adding MA_ASSUME in these places
helps the compiler understand the range of possible values, and know how
heavily to vectorize (or not vectorize) these loops.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
This tells the compiler that pFrameOut does not alias to pointers used
within the function, and teaches Clang that the loop is vectorizable.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
These values are constant, but Clang has some trouble noticing that,
especially if the loop body is complex enough. This prevents it from
noticing places where vectorization is possible (and desirable).
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
This macro can be used to tell the compiler's optimization passes static
assumptions which you *know* are true about code behavior.
Use of these can be risky -- if you assume incorrectly, the compiler may
emit code that will not work in circumstances you didn't anticipate.
On the other hand, use of this macro in places where the optimizer is
missing an assumption that would have been safe to make can cause it to
emit more compact/optimal code.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Both GCC and Clang can use this feature, so let's make it more general.
I didn't touch the dr_wav/dr_flac parts using this, since I figure the
amalgamated miniaudio.h header isn't the primary source for those.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
I had a situation where I was doing:
ma_backend backends[] = {
ma_backend_jack,
ma_backend_wasapi,
};
ma_context_init(backends, sizeof(backends)/sizeof(backends[0]),
&contextConfig, &context);
And since JACK was unavailable, it fell back to WASAPI. When this
happened, the WASAPI commandIndex and commandCount variables were
already stomped on by the JACK backend initialization, but the WASAPI
backend assumes they are zero-initialized.
Signed-off-by: Steven Noonan <steven@uplinklabs.net>
Thread Sanitizer was unhappy about these variables being modified on one
thread and read on another (data race).
Signed-off-by: Steven Noonan <steven@uplinklabs.net>