aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-12-28 11:33:19 -0800
committerChris Robinson <[email protected]>2019-12-28 11:33:19 -0800
commit701d43b41e1976f4a06622df0baa0f284aaaf022 (patch)
tree306c040364bc50b153ecc078d8b8670b3ac97eae
parent3b3d3d3a03c3f39e758b3b9b41649b86314eb413 (diff)
Start a new extension for a new direct_channels state
So existing behavior remains consistent for anything that needs it, and new behavior is opt-in.
-rw-r--r--al/source.cpp9
-rw-r--r--al/source.h2
-rw-r--r--alc/alu.cpp16
-rw-r--r--alc/inprogext.h6
-rw-r--r--alc/voice.h8
5 files changed, 28 insertions, 13 deletions
diff --git a/al/source.cpp b/al/source.cpp
index 75d4a803..9bfeaa24 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -1276,9 +1276,10 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
case AL_DIRECT_CHANNELS_SOFT:
CHECKSIZE(values, 1);
- CHECKVAL(values[0] == AL_FALSE || values[0] == AL_TRUE);
+ CHECKVAL(values[0] == AL_FALSE || values[0] == AL_DROP_UNMATCHED_SOFT /* aka AL_TRUE */
+ || values[0] == AL_REMIX_UNMATCHED_SOFT);
- Source->DirectChannels = values[0] != AL_FALSE;
+ Source->DirectChannels = static_cast<DirectMode>(values[0]);
return UpdateSourceProps(Source, Context);
case AL_DISTANCE_MODEL:
@@ -1826,7 +1827,7 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
case AL_DIRECT_CHANNELS_SOFT:
CHECKSIZE(values, 1);
- values[0] = Source->DirectChannels;
+ values[0] = static_cast<int>(Source->DirectChannels);
return true;
case AL_DISTANCE_MODEL:
@@ -3277,7 +3278,7 @@ ALsource::ALsource(ALuint num_sends)
Looping = AL_FALSE;
mDistanceModel = DistanceModel::Default;
mResampler = ResamplerDefault;
- DirectChannels = AL_FALSE;
+ DirectChannels = DirectMode::Off;
mSpatialize = SpatializeAuto;
StereoPan[0] = Deg2Rad( 30.0f);
diff --git a/al/source.h b/al/source.h
index 7ca889d7..40bd0846 100644
--- a/al/source.h
+++ b/al/source.h
@@ -53,7 +53,7 @@ struct ALsource {
bool Looping;
DistanceModel mDistanceModel;
Resampler mResampler;
- bool DirectChannels;
+ DirectMode DirectChannels;
SpatializeMode mSpatialize;
bool DryGainHFAuto;
diff --git a/alc/alu.cpp b/alc/alu.cpp
index da1d72b9..adc6d435 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -731,7 +731,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo
const auto Frequency = static_cast<ALfloat>(Device->Frequency);
const ALuint NumSends{Device->NumAuxSends};
- bool DirectChannels{props->DirectChannels != AL_FALSE};
+ DirectMode DirectChannels{props->DirectChannels};
const ALuint num_channels{voice->mNumChannels};
const ChanMap *chans{nullptr};
ALfloat downmix_gain{1.0f};
@@ -740,11 +740,11 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo
case FmtMono:
chans = MonoMap;
/* Mono buffers are never played direct. */
- DirectChannels = false;
+ DirectChannels = DirectMode::Off;
break;
case FmtStereo:
- if(!DirectChannels)
+ if(DirectChannels == DirectMode::Off)
{
/* Convert counter-clockwise to clockwise. */
StereoMap[0].angle = -props->StereoPan[0];
@@ -785,7 +785,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo
case FmtBFormat2D:
case FmtBFormat3D:
- DirectChannels = false;
+ DirectChannels = DirectMode::Off;
break;
}
ASSUME(num_channels > 0);
@@ -934,7 +934,8 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo
}
}
}
- else if(DirectChannels && Device->FmtChans != DevFmtMono && Device->FmtChans != DevFmtAmbi3D)
+ else if(DirectChannels != DirectMode::Off && Device->FmtChans != DevFmtMono
+ && Device->FmtChans != DevFmtAmbi3D)
{
/* Direct source channels always play local. Skip the virtual channels
* and write inputs to the matching real outputs.
@@ -946,7 +947,7 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo
ALuint idx{GetChannelIdxByName(Device->RealOut, chans[c].channel)};
if(idx != INVALID_CHANNEL_INDEX)
voice->mChans[c].mDryParams.Gains.Target[idx] = DryGain.Base;
- else
+ else if(DirectChannels == DirectMode::RemixMismatch)
{
auto match_channel = [chans,c](const InputRemixMap &map) noexcept -> bool
{ return chans[c].channel == map.channel; };
@@ -1575,7 +1576,8 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
AtomicReplaceHead(context->mFreeVoiceProps, props);
}
- if(voice->mProps.DirectChannels || voice->mProps.mSpatializeMode == SpatializeOff
+ if(voice->mProps.DirectChannels != DirectMode::Off
+ || voice->mProps.mSpatializeMode == SpatializeOff
|| (voice->mProps.mSpatializeMode == SpatializeAuto && voice->mFmtChannels != FmtMono))
CalcNonAttnSourceParams(voice, &voice->mProps, context);
else
diff --git a/alc/inprogext.h b/alc/inprogext.h
index d1890e70..17638e52 100644
--- a/alc/inprogext.h
+++ b/alc/inprogext.h
@@ -92,6 +92,12 @@ AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values);
#define AL_N3D_SOFT 0x0002
#endif
+#ifndef AL_SOFT_direct_channels_remix
+#define AL_SOFT_direct_channels_remix
+#define AL_DROP_UNMATCHED_SOFT 0x0001
+#define AL_REMIX_UNMATCHED_SOFT 0x0002
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/alc/voice.h b/alc/voice.h
index 67678cd9..4bfee7bc 100644
--- a/alc/voice.h
+++ b/alc/voice.h
@@ -24,6 +24,12 @@ enum SpatializeMode {
SpatializeAuto = AL_AUTO_SOFT
};
+enum class DirectMode : unsigned char {
+ Off = AL_FALSE,
+ DropMismatch = AL_DROP_UNMATCHED_SOFT,
+ RemixMismatch = AL_REMIX_UNMATCHED_SOFT
+};
+
enum class Resampler {
Point,
Linear,
@@ -134,7 +140,7 @@ struct ALvoicePropsBase {
bool HeadRelative;
DistanceModel mDistanceModel;
Resampler mResampler;
- bool DirectChannels;
+ DirectMode DirectChannels;
SpatializeMode mSpatializeMode;
bool DryGainHFAuto;