aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c2
-rw-r--r--Alc/ALu.c64
-rw-r--r--OpenAL32/Include/alMain.h5
-rw-r--r--OpenAL32/Include/alSource.h1
-rw-r--r--OpenAL32/alExtension.c1
-rw-r--r--OpenAL32/alSource.c17
6 files changed, 72 insertions, 18 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 65984934..d880441e 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -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;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 8bfe305b..845436a5 100644
--- a/Alc/ALu.c
+++ b/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;
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 3264d5ed..ebf1b20e 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -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>
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 9cbd7f54..8afe8281 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -46,6 +46,7 @@ typedef struct ALsource
ALboolean bHeadRelative;
ALboolean bLooping;
ALenum DistanceModel;
+ ALboolean VirtualChannels;
resampler_t Resampler;
diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c
index eb0f46a8..ebb2e252 100644
--- a/OpenAL32/alExtension.c
+++ b/OpenAL32/alExtension.c
@@ -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 },
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index e91206eb..a1319005 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -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;