Use a bitset instead of a plain uint for flags

This commit is contained in:
Chris Robinson 2021-12-23 13:43:10 -08:00
parent 0af1b5f721
commit f1aa10ff0b
4 changed files with 42 additions and 37 deletions

View File

@ -503,8 +503,8 @@ void InitVoice(Voice *voice, ALsource *source, ALbufferQueueItem *BufferList, AL
voice->mAmbiScaling = IsUHJ(voice->mFmtChannels) ? AmbiScaling::UHJ : buffer->mAmbiScaling; voice->mAmbiScaling = IsUHJ(voice->mFmtChannels) ? AmbiScaling::UHJ : buffer->mAmbiScaling;
voice->mAmbiOrder = (voice->mFmtChannels == FmtSuperStereo) ? 1 : buffer->mAmbiOrder; voice->mAmbiOrder = (voice->mFmtChannels == FmtSuperStereo) ? 1 : buffer->mAmbiOrder;
if(buffer->mCallback) voice->mFlags |= VoiceIsCallback; if(buffer->mCallback) voice->mFlags.set(VoiceIsCallback);
else if(source->SourceType == AL_STATIC) voice->mFlags |= VoiceIsStatic; else if(source->SourceType == AL_STATIC) voice->mFlags.set(VoiceIsStatic);
voice->mNumCallbackSamples = 0; voice->mNumCallbackSamples = 0;
voice->prepare(device); voice->prepare(device);
@ -613,9 +613,9 @@ bool SetVoiceOffset(Voice *oldvoice, const VoicePos &vpos, ALsource *source, ALC
newvoice->mPosition.store(vpos.pos, std::memory_order_relaxed); newvoice->mPosition.store(vpos.pos, std::memory_order_relaxed);
newvoice->mPositionFrac.store(vpos.frac, std::memory_order_relaxed); newvoice->mPositionFrac.store(vpos.frac, std::memory_order_relaxed);
newvoice->mCurrentBuffer.store(vpos.bufferitem, std::memory_order_relaxed); newvoice->mCurrentBuffer.store(vpos.bufferitem, std::memory_order_relaxed);
newvoice->mFlags = 0u; newvoice->mFlags.reset();
if(vpos.pos > 0 || vpos.frac > 0 || vpos.bufferitem != &source->mQueue.front()) if(vpos.pos > 0 || vpos.frac > 0 || vpos.bufferitem != &source->mQueue.front())
newvoice->mFlags |= VoiceIsFading; newvoice->mFlags.set(VoiceIsFading);
InitVoice(newvoice, source, vpos.bufferitem, context, device); InitVoice(newvoice, source, vpos.bufferitem, context, device);
source->VoiceIdx = vidx; source->VoiceIdx = vidx;
@ -1268,7 +1268,7 @@ bool SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
if(Voice *voice{GetSourceVoice(Source, Context)}) if(Voice *voice{GetSourceVoice(Source, Context)})
{ {
if((voice->mFlags&VoiceIsCallback)) if(voice->mFlags.test(VoiceIsCallback))
SETERR_RETURN(Context, AL_INVALID_VALUE, false, SETERR_RETURN(Context, AL_INVALID_VALUE, false,
"Source offset for callback is invalid"); "Source offset for callback is invalid");
auto vpos = GetSampleOffset(Source->mQueue, prop, values[0]); auto vpos = GetSampleOffset(Source->mQueue, prop, values[0]);
@ -1494,7 +1494,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
if(Voice *voice{GetSourceVoice(Source, Context)}) if(Voice *voice{GetSourceVoice(Source, Context)})
{ {
if((voice->mFlags&VoiceIsCallback)) if(voice->mFlags.test(VoiceIsCallback))
SETERR_RETURN(Context, AL_INVALID_VALUE, false, SETERR_RETURN(Context, AL_INVALID_VALUE, false,
"Source offset for callback is invalid"); "Source offset for callback is invalid");
auto vpos = GetSampleOffset(Source->mQueue, prop, values[0]); auto vpos = GetSampleOffset(Source->mQueue, prop, values[0]);
@ -3117,7 +3117,7 @@ START_API_FUNC
voice->mPosition.store(0u, std::memory_order_relaxed); voice->mPosition.store(0u, std::memory_order_relaxed);
voice->mPositionFrac.store(0, std::memory_order_relaxed); voice->mPositionFrac.store(0, std::memory_order_relaxed);
voice->mCurrentBuffer.store(&source->mQueue.front(), std::memory_order_relaxed); voice->mCurrentBuffer.store(&source->mQueue.front(), std::memory_order_relaxed);
voice->mFlags = 0; voice->mFlags.reset();
/* A source that's not playing or paused has any offset applied when it /* A source that's not playing or paused has any offset applied when it
* starts playing. * starts playing.
*/ */
@ -3132,7 +3132,7 @@ START_API_FUNC
voice->mPositionFrac.store(vpos->frac, std::memory_order_relaxed); voice->mPositionFrac.store(vpos->frac, std::memory_order_relaxed);
voice->mCurrentBuffer.store(vpos->bufferitem, std::memory_order_relaxed); voice->mCurrentBuffer.store(vpos->bufferitem, std::memory_order_relaxed);
if(vpos->pos!=0 || vpos->frac!=0 || vpos->bufferitem!=&source->mQueue.front()) if(vpos->pos!=0 || vpos->frac!=0 || vpos->bufferitem!=&source->mQueue.front())
voice->mFlags |= VoiceIsFading; voice->mFlags.set(VoiceIsFading);
} }
} }
InitVoice(voice, source, std::addressof(*BufferList), context.get(), device); InitVoice(voice, source, std::addressof(*BufferList), context.get(), device);

View File

@ -776,7 +776,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
break; break;
} }
voice->mFlags &= ~(VoiceHasHrtf | VoiceHasNfc); voice->mFlags.reset(VoiceHasHrtf).reset(VoiceHasNfc);
if(auto *decoder{voice->mDecoder.get()}) if(auto *decoder{voice->mDecoder.get()})
decoder->mWidthControl = props->EnhWidth; decoder->mWidthControl = props->EnhWidth;
@ -807,7 +807,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
voice->mChans[0].mDryParams.NFCtrlFilter.adjust(w0); voice->mChans[0].mDryParams.NFCtrlFilter.adjust(w0);
} }
voice->mFlags |= VoiceHasNfc; voice->mFlags.set(VoiceHasNfc);
} }
/* Panning a B-Format sound toward some direction is easy. Just pan the /* Panning a B-Format sound toward some direction is easy. Just pan the
@ -1040,7 +1040,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
} }
} }
voice->mFlags |= VoiceHasHrtf; voice->mFlags.set(VoiceHasHrtf);
} }
else else
{ {
@ -1061,7 +1061,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
for(size_t c{0};c < num_channels;c++) for(size_t c{0};c < num_channels;c++)
voice->mChans[c].mDryParams.NFCtrlFilter.adjust(w0); voice->mChans[c].mDryParams.NFCtrlFilter.adjust(w0);
voice->mFlags |= VoiceHasNfc; voice->mFlags.set(VoiceHasNfc);
} }
/* Calculate the directional coefficients once, which apply to all /* Calculate the directional coefficients once, which apply to all
@ -1112,7 +1112,7 @@ void CalcPanningAndFilters(Voice *voice, const float xpos, const float ypos, con
for(size_t c{0};c < num_channels;c++) for(size_t c{0};c < num_channels;c++)
voice->mChans[c].mDryParams.NFCtrlFilter.adjust(w0); voice->mChans[c].mDryParams.NFCtrlFilter.adjust(w0);
voice->mFlags |= VoiceHasNfc; voice->mFlags.set(VoiceHasNfc);
} }
for(size_t c{0};c < num_channels;c++) for(size_t c{0};c < num_channels;c++)

View File

@ -482,7 +482,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
ResamplerFunc Resample{(increment == MixerFracOne && DataPosFrac == 0) ? ResamplerFunc Resample{(increment == MixerFracOne && DataPosFrac == 0) ?
Resample_<CopyTag,CTag> : mResampler}; Resample_<CopyTag,CTag> : mResampler};
uint Counter{(mFlags&VoiceIsFading) ? SamplesToDo : 0}; uint Counter{mFlags.test(VoiceIsFading) ? SamplesToDo : 0};
if(!Counter) if(!Counter)
{ {
/* No fading, just overwrite the old/current params. */ /* No fading, just overwrite the old/current params. */
@ -490,7 +490,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
{ {
{ {
DirectParams &parms = chandata.mDryParams; DirectParams &parms = chandata.mDryParams;
if(!(mFlags&VoiceHasHrtf)) if(!mFlags.test(VoiceHasHrtf))
parms.Gains.Current = parms.Gains.Target; parms.Gains.Current = parms.Gains.Target;
else else
parms.Hrtf.Old = parms.Hrtf.Target; parms.Hrtf.Old = parms.Hrtf.Target;
@ -592,12 +592,12 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
std::copy_n(prevSamples->data(), MaxResamplerEdge, chanbuffer.data()); std::copy_n(prevSamples->data(), MaxResamplerEdge, chanbuffer.data());
++prevSamples; ++prevSamples;
} }
if((mFlags&VoiceIsStatic)) if(mFlags.test(VoiceIsStatic))
LoadBufferStatic(BufferListItem, BufferLoopItem, DataPosInt, mFmtType, LoadBufferStatic(BufferListItem, BufferLoopItem, DataPosInt, mFmtType,
mFmtChannels, mFrameStep, SrcBufferSize, MixingSamples); mFmtChannels, mFrameStep, SrcBufferSize, MixingSamples);
else if((mFlags&VoiceIsCallback)) else if(mFlags.test(VoiceIsCallback))
{ {
if(!(mFlags&VoiceCallbackStopped)) if(!mFlags.test(VoiceCallbackStopped))
{ {
if(SrcBufferSize > mNumCallbackSamples) if(SrcBufferSize > mNumCallbackSamples)
{ {
@ -607,10 +607,10 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData, const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData,
&BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))}; &BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))};
if(gotBytes < 0) if(gotBytes < 0)
mFlags |= VoiceCallbackStopped; mFlags.set(VoiceCallbackStopped);
else if(static_cast<uint>(gotBytes) < needBytes) else if(static_cast<uint>(gotBytes) < needBytes)
{ {
mFlags |= VoiceCallbackStopped; mFlags.set(VoiceCallbackStopped);
mNumCallbackSamples += static_cast<uint>(static_cast<uint>(gotBytes) / mNumCallbackSamples += static_cast<uint>(static_cast<uint>(gotBytes) /
mFrameSize); mFrameSize);
} }
@ -650,7 +650,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
voiceSamples->data() + MaxResamplerEdge, DataPosFrac, increment, voiceSamples->data() + MaxResamplerEdge, DataPosFrac, increment,
{Device->ResampledData, DstBufferSize})}; {Device->ResampledData, DstBufferSize})};
++voiceSamples; ++voiceSamples;
if((mFlags&VoiceIsAmbisonic)) if(mFlags.test(VoiceIsAmbisonic))
chandata.mAmbiSplitter.processScale({ResampledData, DstBufferSize}, chandata.mAmbiSplitter.processScale({ResampledData, DstBufferSize},
chandata.mAmbiHFScale, chandata.mAmbiLFScale); chandata.mAmbiHFScale, chandata.mAmbiLFScale);
@ -661,7 +661,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf.data(), const float *samples{DoFilters(parms.LowPass, parms.HighPass, FilterBuf.data(),
{ResampledData, DstBufferSize}, mDirect.FilterType)}; {ResampledData, DstBufferSize}, mDirect.FilterType)};
if((mFlags&VoiceHasHrtf)) if(mFlags.test(VoiceHasHrtf))
{ {
const float TargetGain{parms.Hrtf.Target.Gain * likely(vstate == Playing)}; const float TargetGain{parms.Hrtf.Target.Gain * likely(vstate == Playing)};
DoHrtfMix(samples, DstBufferSize, parms, TargetGain, Counter, OutPos, DoHrtfMix(samples, DstBufferSize, parms, TargetGain, Counter, OutPos,
@ -671,7 +671,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
{ {
const float *TargetGains{likely(vstate == Playing) ? parms.Gains.Target.data() const float *TargetGains{likely(vstate == Playing) ? parms.Gains.Target.data()
: SilentTarget.data()}; : SilentTarget.data()};
if((mFlags&VoiceHasNfc)) if(mFlags.test(VoiceHasNfc))
DoNfcMix({samples, DstBufferSize}, mDirect.Buffer.data(), parms, DoNfcMix({samples, DstBufferSize}, mDirect.Buffer.data(), parms,
TargetGains, Counter, OutPos, Device); TargetGains, Counter, OutPos, Device);
else else
@ -708,7 +708,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
{ {
/* Do nothing extra when there's no buffers. */ /* Do nothing extra when there's no buffers. */
} }
else if((mFlags&VoiceIsStatic)) else if(mFlags.test(VoiceIsStatic))
{ {
if(BufferLoopItem) if(BufferLoopItem)
{ {
@ -731,7 +731,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
} }
} }
} }
else if((mFlags&VoiceIsCallback)) else if(mFlags.test(VoiceIsCallback))
{ {
/* Don't use up the stored callback samples when stopping (pausing) /* Don't use up the stored callback samples when stopping (pausing)
* since they'll be replayed when resuming. * since they'll be replayed when resuming.
@ -769,7 +769,7 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
} }
} while(OutPos < SamplesToDo && likely(vstate == Playing)); } while(OutPos < SamplesToDo && likely(vstate == Playing));
mFlags |= VoiceIsFading; mFlags.set(VoiceIsFading);
/* Don't update positions and buffers if we were stopping. */ /* Don't update positions and buffers if we were stopping. */
if(unlikely(vstate == Stopping)) if(unlikely(vstate == Stopping))
@ -898,7 +898,7 @@ void Voice::prepare(DeviceBase *device)
mChans[1].mAmbiLFScale = 1.293f; mChans[1].mAmbiLFScale = 1.293f;
mChans[2].mAmbiLFScale = 1.293f; mChans[2].mAmbiLFScale = 1.293f;
} }
mFlags |= VoiceIsAmbisonic; mFlags.set(VoiceIsAmbisonic);
} }
else if(mFmtChannels == FmtUHJ2 && !device->mUhjEncoder) else if(mFmtChannels == FmtUHJ2 && !device->mUhjEncoder)
{ {
@ -919,7 +919,7 @@ void Voice::prepare(DeviceBase *device)
mChans[0].mAmbiLFScale = 0.661f; mChans[0].mAmbiLFScale = 0.661f;
mChans[1].mAmbiLFScale = 1.293f; mChans[1].mAmbiLFScale = 1.293f;
mChans[2].mAmbiLFScale = 1.293f; mChans[2].mAmbiLFScale = 1.293f;
mFlags |= VoiceIsAmbisonic; mFlags.set(VoiceIsAmbisonic);
} }
else else
{ {
@ -929,6 +929,6 @@ void Voice::prepare(DeviceBase *device)
chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter; chandata.mDryParams.NFCtrlFilter = device->mNFCtrlFilter;
std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{}); std::fill_n(chandata.mWetParams.begin(), device->NumAuxSends, SendParams{});
} }
mFlags &= ~VoiceIsAmbisonic; mFlags.reset(VoiceIsAmbisonic);
} }
} }

View File

@ -3,6 +3,7 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <bitset>
#include <memory> #include <memory>
#include <stddef.h> #include <stddef.h>
#include <string> #include <string>
@ -164,13 +165,17 @@ struct VoicePropsItem : public VoiceProps {
DEF_NEWDEL(VoicePropsItem) DEF_NEWDEL(VoicePropsItem)
}; };
constexpr uint VoiceIsStatic{ 1u<<0}; enum : uint {
constexpr uint VoiceIsCallback{ 1u<<1}; VoiceIsStatic,
constexpr uint VoiceIsAmbisonic{ 1u<<2}; /* Needs HF scaling for ambisonic upsampling. */ VoiceIsCallback,
constexpr uint VoiceCallbackStopped{1u<<3}; VoiceIsAmbisonic,
constexpr uint VoiceIsFading{ 1u<<4}; /* Use gain stepping for smooth transitions. */ VoiceCallbackStopped,
constexpr uint VoiceHasHrtf{ 1u<<5}; VoiceIsFading,
constexpr uint VoiceHasNfc{ 1u<<6}; VoiceHasHrtf,
VoiceHasNfc,
VoiceFlagCount
};
struct Voice { struct Voice {
enum State { enum State {
@ -224,7 +229,7 @@ struct Voice {
InterpState mResampleState; InterpState mResampleState;
uint mFlags{}; std::bitset<VoiceFlagCount> mFlags{};
uint mNumCallbackSamples{0}; uint mNumCallbackSamples{0};
struct TargetData { struct TargetData {