Add a source property to skip channel virtualization for multi-channel buffers
With virtualization disabled, channels are mapped directly from input to output and any input channel that is missing an output is dropped. Any virtualization effects (such as HRTF filters) for positional cues are also skipped. The idea is to allow applications a way to play pre-filtered audio that channel vitualization effects could interfere with.
This commit is contained in:
parent
1b773a8585
commit
5736bbc3e4
@ -389,7 +389,7 @@ static const ALchar alExtList[] =
|
||||
"AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
|
||||
"AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
|
||||
"AL_LOKI_quadriphonic AL_SOFTX_buffer_samples AL_SOFT_buffer_sub_data "
|
||||
"AL_SOFT_loop_points";
|
||||
"AL_SOFT_loop_points AL_SOFTX_non_virtual_channels";
|
||||
|
||||
// Mixing Priority Level
|
||||
static ALint RTPrioLevel;
|
||||
|
64
Alc/ALu.c
64
Alc/ALu.c
@ -89,6 +89,22 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
static const ALfloat angles_X71[8] = { -30.0f, 30.0f, 0.0f, 0.0f,
|
||||
-110.0f, 110.0f, -90.0f, 90.0f };
|
||||
|
||||
static const Channel chans_Mono[1] = { FRONT_CENTER };
|
||||
static const Channel chans_Stereo[2] = { FRONT_LEFT, FRONT_RIGHT };
|
||||
static const Channel chans_Rear[2] = { BACK_LEFT, BACK_RIGHT };
|
||||
static const Channel chans_Quad[4] = { FRONT_LEFT, FRONT_RIGHT,
|
||||
BACK_LEFT, BACK_RIGHT };
|
||||
static const Channel chans_X51[6] = { FRONT_LEFT, FRONT_RIGHT,
|
||||
FRONT_CENTER, LFE,
|
||||
BACK_LEFT, BACK_RIGHT };
|
||||
static const Channel chans_X61[7] = { FRONT_LEFT, FRONT_RIGHT,
|
||||
FRONT_CENTER, LFE, BACK_CENTER,
|
||||
SIDE_LEFT, SIDE_RIGHT };
|
||||
static const Channel chans_X71[8] = { FRONT_LEFT, FRONT_RIGHT,
|
||||
FRONT_CENTER, LFE,
|
||||
BACK_LEFT, BACK_RIGHT,
|
||||
SIDE_LEFT, SIDE_RIGHT };
|
||||
|
||||
ALCdevice *Device = ALContext->Device;
|
||||
ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
|
||||
ALbufferlistitem *BufferListItem;
|
||||
@ -101,8 +117,9 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
ALint NumSends, Frequency;
|
||||
const ALfloat *SpeakerGain;
|
||||
const ALfloat *angles = NULL;
|
||||
const Channel *chans = NULL;
|
||||
ALint num_channels = 0;
|
||||
ALint lfe_chan = -1;
|
||||
ALboolean VirtualChannels;
|
||||
ALfloat Pitch;
|
||||
ALfloat cw;
|
||||
ALuint pos;
|
||||
@ -117,10 +134,11 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
ListenerGain = ALContext->Listener.Gain;
|
||||
|
||||
/* Get source properties */
|
||||
SourceVolume = ALSource->flGain;
|
||||
MinVolume = ALSource->flMinGain;
|
||||
MaxVolume = ALSource->flMaxGain;
|
||||
Pitch = ALSource->flPitch;
|
||||
SourceVolume = ALSource->flGain;
|
||||
MinVolume = ALSource->flMinGain;
|
||||
MaxVolume = ALSource->flMaxGain;
|
||||
Pitch = ALSource->flPitch;
|
||||
VirtualChannels = ALSource->VirtualChannels;
|
||||
|
||||
/* Calculate the stepping value */
|
||||
Channels = FmtMono;
|
||||
@ -148,11 +166,14 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
|
||||
Channels = ALBuffer->FmtChannels;
|
||||
|
||||
ALSource->Params.DoMix = ((Device->Flags&DEVICE_USE_HRTF) ?
|
||||
SelectHrtfMixer(ALBuffer, (ALSource->Params.Step==FRACTIONONE) ?
|
||||
POINT_RESAMPLER : ALSource->Resampler) :
|
||||
SelectMixer(ALBuffer, (ALSource->Params.Step==FRACTIONONE) ?
|
||||
POINT_RESAMPLER : ALSource->Resampler));
|
||||
if(ALSource->VirtualChannels && (Device->Flags&DEVICE_USE_HRTF))
|
||||
ALSource->Params.DoMix = SelectHrtfMixer(ALBuffer,
|
||||
(ALSource->Params.Step==FRACTIONONE) ? POINT_RESAMPLER :
|
||||
ALSource->Resampler);
|
||||
else
|
||||
ALSource->Params.DoMix = SelectMixer(ALBuffer,
|
||||
(ALSource->Params.Step==FRACTIONONE) ? POINT_RESAMPLER :
|
||||
ALSource->Resampler);
|
||||
break;
|
||||
}
|
||||
BufferListItem = BufferListItem->next;
|
||||
@ -182,10 +203,11 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
{
|
||||
case FmtMono:
|
||||
angles = angles_Mono;
|
||||
chans = chans_Mono;
|
||||
num_channels = 1;
|
||||
break;
|
||||
case FmtStereo:
|
||||
if((ALContext->Device->Flags&DEVICE_DUPLICATE_STEREO))
|
||||
if(VirtualChannels && (ALContext->Device->Flags&DEVICE_DUPLICATE_STEREO))
|
||||
{
|
||||
DryGain *= aluSqrt(2.0f/4.0f);
|
||||
for(c = 0;c < 2;c++)
|
||||
@ -203,45 +225,53 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
}
|
||||
}
|
||||
angles = angles_Stereo;
|
||||
chans = chans_Stereo;
|
||||
num_channels = 2;
|
||||
break;
|
||||
|
||||
case FmtRear:
|
||||
angles = angles_Rear;
|
||||
chans = chans_Rear;
|
||||
num_channels = 2;
|
||||
break;
|
||||
|
||||
case FmtQuad:
|
||||
angles = angles_Quad;
|
||||
chans = chans_Quad;
|
||||
num_channels = 4;
|
||||
break;
|
||||
|
||||
case FmtX51:
|
||||
angles = angles_X51;
|
||||
chans = chans_X51;
|
||||
num_channels = 6;
|
||||
lfe_chan = 3;
|
||||
break;
|
||||
|
||||
case FmtX61:
|
||||
angles = angles_X61;
|
||||
chans = chans_X61;
|
||||
num_channels = 7;
|
||||
lfe_chan = 3;
|
||||
break;
|
||||
|
||||
case FmtX71:
|
||||
angles = angles_X71;
|
||||
chans = chans_X71;
|
||||
num_channels = 8;
|
||||
lfe_chan = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
if((Device->Flags&DEVICE_USE_HRTF))
|
||||
if(VirtualChannels == AL_FALSE)
|
||||
{
|
||||
for(c = 0;c < num_channels;c++)
|
||||
SrcMatrix[c][chans[c]] += DryGain * ListenerGain;
|
||||
}
|
||||
else if((Device->Flags&DEVICE_USE_HRTF))
|
||||
{
|
||||
for(c = 0;c < num_channels;c++)
|
||||
{
|
||||
const ALshort *hrtf_left, *hrtf_right;
|
||||
|
||||
if(c == lfe_chan)
|
||||
if(chans[c] == LFE)
|
||||
{
|
||||
/* Skip LFE */
|
||||
ALSource->Params.HrtfDelay[c][0] = 0;
|
||||
@ -271,7 +301,7 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
|
||||
{
|
||||
for(c = 0;c < num_channels;c++)
|
||||
{
|
||||
if(c == lfe_chan) /* Special-case LFE */
|
||||
if(chans[c] == LFE) /* Special-case LFE */
|
||||
{
|
||||
SrcMatrix[c][LFE] += DryGain * ListenerGain;
|
||||
continue;
|
||||
|
@ -93,6 +93,11 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_non_virtual_channels
|
||||
#define AL_SOFT_non_virtual_channels 1
|
||||
#define AL_VIRTUAL_CHANNELS_SOFT 0x1033
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
|
@ -46,6 +46,7 @@ typedef struct ALsource
|
||||
ALboolean bHeadRelative;
|
||||
ALboolean bLooping;
|
||||
ALenum DistanceModel;
|
||||
ALboolean VirtualChannels;
|
||||
|
||||
resampler_t Resampler;
|
||||
|
||||
|
@ -75,6 +75,7 @@ static const ALenums enumeration[] = {
|
||||
{ "AL_STREAMING", AL_STREAMING },
|
||||
{ "AL_UNDETERMINED", AL_UNDETERMINED },
|
||||
{ "AL_METERS_PER_UNIT", AL_METERS_PER_UNIT },
|
||||
{ "AL_VIRTUAL_CHANNELS_SOFT", AL_VIRTUAL_CHANNELS_SOFT },
|
||||
|
||||
// Source EFX Properties
|
||||
{ "AL_DIRECT_FILTER", AL_DIRECT_FILTER },
|
||||
|
@ -680,6 +680,16 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue)
|
||||
alSetError(pContext, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_VIRTUAL_CHANNELS_SOFT:
|
||||
if(lValue == AL_TRUE || lValue == AL_FALSE)
|
||||
{
|
||||
Source->VirtualChannels = lValue;
|
||||
Source->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(pContext, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
if(lValue == AL_NONE ||
|
||||
lValue == AL_INVERSE_DISTANCE ||
|
||||
@ -801,6 +811,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum eParam, const ALint* pl
|
||||
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
|
||||
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_VIRTUAL_CHANNELS_SOFT:
|
||||
alSourcei(source, eParam, plValues[0]);
|
||||
return;
|
||||
|
||||
@ -1149,6 +1160,10 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum eParam, ALint *plVa
|
||||
*plValue = (ALint)Source->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_VIRTUAL_CHANNELS_SOFT:
|
||||
*plValue = Source->VirtualChannels;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
*plValue = Source->DistanceModel;
|
||||
break;
|
||||
@ -1245,6 +1260,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum eParam, ALint* plVal
|
||||
case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO:
|
||||
case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO:
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_VIRTUAL_CHANNELS_SOFT:
|
||||
alGetSourcei(source, eParam, plValues);
|
||||
return;
|
||||
|
||||
@ -1807,6 +1823,7 @@ static ALvoid InitSourceParams(ALsource *Source)
|
||||
Source->AirAbsorptionFactor = 0.0f;
|
||||
Source->RoomRolloffFactor = 0.0f;
|
||||
Source->DopplerFactor = 1.0f;
|
||||
Source->VirtualChannels = AL_TRUE;
|
||||
|
||||
Source->DistanceModel = AL_INVERSE_DISTANCE_CLAMPED;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user