| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This has a couple behavioral changes. First and biggest is that querying
AL_BUFFERS_PROCESSED from a source will always return all buffers processed
when in an AL_STOPPED state. Previously all buffers would be set as processed
when first becoming stopped, but newly queued buffers would *not* be indicated
as processed. That old behavior was not compliant with the spec, which
unequivocally states "On a source in the AL_STOPPED state, all buffers are
processed."
Secondly, querying AL_BUFFER on an AL_STREAMING source will now always return
0. Previously it would return the current "active" buffer in the queue, but
there's no basis for that in the spec.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This change allows pair-wise panning to mostly go through the normal ambisonic
panning methods, with one special-case. First, a term is added to the stereo
decoder matrix's X coefficient so that a centered sound is reduced by -3dB on
each output channel. Panning in front creates a similar gain response to the
typical
L = sqrt(1-pan)
R = sqrt(pan)
for pan = [0,1]. Panning behind the listener can reduce (up to) an additional
-10dB, creating a audible difference between front and back sounds as if
simulating head obstruction.
Secondly, as a special-case, the source positions are warped when calculating
the ambisonic coefficients so that full left panning is reached at -30 degrees
and full right at +30 degrees. This is to retain the expected 60-degree stereo
width. This warping does not apply to B-Format buffer input, although it
otherwise has the same gain responses.
|
|
|
|
| |
Also rename the 'paired' value to 'panpot', and make it the default.
|
| |
|
| |
|
|
|
|
|
| |
The voices are still all allocated in one chunk to avoid memory fragmentation.
But they're accessed as an array of pointers since the size isn't static.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
This places the Send[] array at the end of the struct, making it easier to
handle dynamically.
|
|
|
|
|
|
| |
ALsourceProps' Send[] array is placed at the end of the struct, and given an
indeterminate size. Extra space is allocated at the end of each struct given
the number of auxiliary sends set for the device.
|
|
|
|
|
| |
Since it's modified by the mixer when playback is ended, a plain struct member
isn't safe.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
Unsigned 32-bit offsets actually have some potential overhead on 64-bit targets
for pointer/array accesses due to rules on integer wrapping. No idea how much
impact it has in practice, but it's nice to be correct about it.
|
|
|
|
|
|
| |
This should improve positional quality for relatively low cost. Full HRTF
rendering still only uses first-order since the only use of the dry buffer
there is for first-order content (B-Format buffers, effects).
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
It still fades between HRIRs when it changes, but now it selects the nearest
one instead of blending the nearest four. Due to the minimum-phase nature of
the HRIRs, interpolating between delays lead to some oddities which are
exasperated by the fading (and the fading is needed to avoid clicks and pops,
and smooth out changes).
|
| |
|
|
|
|
|
|
|
|
|
| |
Designed for apps that either don't change the listener's AL_GAIN, or don't
allow the listener's AL_GAIN to go above 1. This allows the volume to still be
increased further than such apps may allow, if users find it too quiet.
Be aware that increasing this can easily cause clipping. The gain limit
reported by AL_GAIN_LIMIT_SOFT is also affected by this.
|
| |
|
| |
|
|
|
|
|
|
| |
The combined source and listener gains now can't exceed a multiplier of 16
(~24dB). This is to avoid mixes getting out of control with large volume
boosts, which reduces the effective precision given by floating-point.
|
|
|
|
|
|
|
|
| |
Note that this now also causes all playing sources to update when an effect
slot is updated. This is a bit wasteful, as it should only need to re-update
sources that are using the effect slot (and only when a relevant property is
changed), but it's good enough. Especially with deferring since all playing
sources are going to get updated on the process call anyway.
|
|
|
|
|
|
|
|
| |
This allows us to not have to play around with trying to avoid duplicate state
pointers, since the reference count will ensure they're deleted as appropriate.
The only caveat is that the mixer is not allowed to decrement references, since
that can cause the object to be freed (which the mixer code is not allowed to
do).
|
| |
|
| |
|
| |
|
|
|
|
|
| |
The source's voice holds a copy of the last properties it received, so listener
updates can make sources recalculate internal properties from that stored copy.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Last time this attempted to average the HRIRs according to their contribution
to a given B-Format channel as if they were loudspeakers, as well as averaging
the HRIR delays. The latter part resulted in the loss of the ITD (inter-aural
time delay), a key component of HRTF.
This time, the HRIRs are averaged similar to above, except instead of averaging
the delays, they're applied to the resulting coefficients (for example, a delay
of 8 would apply the HRIR starting at the 8th sample of the target HRIR). This
does roughly double the IR length, as the largest delay is about 35 samples
while the filter is normally 32 samples. However, this is still smaller the
original data set IR (which was 256 samples), it also only needs to be applied
to 4 channels for first-order ambisonics, rather than the 8-channel cube. So
it's doing twice as much work per sample, but only working on half the number
of samples.
Additionally, since the resulting HRIRs no longer rely on an extra delay line,
a more efficient HRTF mixing function can be made that doesn't use one. Such a
function can also avoid the per-sample stepping parameters the original uses.
|
| |
|
|
|
|
|
| |
Certain operations on the buffer queue depend on the loop state to behave
properly, so it should not be deferred until the async voice update occurs.
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
Sometimes the mixer is temporarily prevented from applying updates, when
multiple sources need to be updated simultaneously for example, but does not
prevent mixing. If the mixer runs during that time and a voice was just
started, it would've mixed the voice without any internal properties being set
for it.
|
| |
|
| |
|