Make PopCount and CountTrailingZeros more standard-like
This commit is contained in:
parent
5ff5fd8ecc
commit
da59ad5105
@ -35,6 +35,7 @@
|
|||||||
#include "AL/alc.h"
|
#include "AL/alc.h"
|
||||||
#include "AL/efx.h"
|
#include "AL/efx.h"
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alcontext.h"
|
#include "alcontext.h"
|
||||||
#include "almalloc.h"
|
#include "almalloc.h"
|
||||||
@ -240,7 +241,7 @@ bool EnsureEffectSlots(ALCcontext *context, size_t needed)
|
|||||||
size_t count{std::accumulate(context->mEffectSlotList.cbegin(),
|
size_t count{std::accumulate(context->mEffectSlotList.cbegin(),
|
||||||
context->mEffectSlotList.cend(), size_t{0},
|
context->mEffectSlotList.cend(), size_t{0},
|
||||||
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
|
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
|
{ return cur + static_cast<ALuint>(al::popcount(sublist.FreeMask)); })};
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
@ -268,7 +269,7 @@ ALeffectslot *AllocEffectSlot(ALCcontext *context)
|
|||||||
[](const EffectSlotSubList &entry) noexcept -> bool
|
[](const EffectSlotSubList &entry) noexcept -> bool
|
||||||
{ return entry.FreeMask != 0; });
|
{ return entry.FreeMask != 0; });
|
||||||
auto lidx = static_cast<ALuint>(std::distance(context->mEffectSlotList.begin(), sublist));
|
auto lidx = static_cast<ALuint>(std::distance(context->mEffectSlotList.begin(), sublist));
|
||||||
auto slidx = static_cast<ALuint>(CountTrailingZeros(sublist->FreeMask));
|
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
|
||||||
|
|
||||||
ALeffectslot *slot{::new(sublist->EffectSlots + slidx) ALeffectslot{}};
|
ALeffectslot *slot{::new(sublist->EffectSlots + slidx) ALeffectslot{}};
|
||||||
aluInitEffectPanning(&slot->mSlot, context);
|
aluInitEffectPanning(&slot->mSlot, context);
|
||||||
@ -991,7 +992,7 @@ void UpdateAllEffectSlotProps(ALCcontext *context)
|
|||||||
uint64_t usemask{~sublist.FreeMask};
|
uint64_t usemask{~sublist.FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const int idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
ALeffectslot *slot{sublist.EffectSlots + idx};
|
ALeffectslot *slot{sublist.EffectSlots + idx};
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
|
|
||||||
@ -1007,7 +1008,7 @@ EffectSlotSubList::~EffectSlotSubList()
|
|||||||
uint64_t usemask{~FreeMask};
|
uint64_t usemask{~FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
al::destroy_at(EffectSlots+idx);
|
al::destroy_at(EffectSlots+idx);
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "AL/alc.h"
|
#include "AL/alc.h"
|
||||||
#include "AL/alext.h"
|
#include "AL/alext.h"
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "albyte.h"
|
#include "albyte.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alcontext.h"
|
#include "alcontext.h"
|
||||||
@ -326,7 +327,7 @@ bool EnsureBuffers(ALCdevice *device, size_t needed)
|
|||||||
{
|
{
|
||||||
size_t count{std::accumulate(device->BufferList.cbegin(), device->BufferList.cend(), size_t{0},
|
size_t count{std::accumulate(device->BufferList.cbegin(), device->BufferList.cend(), size_t{0},
|
||||||
[](size_t cur, const BufferSubList &sublist) noexcept -> size_t
|
[](size_t cur, const BufferSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
|
{ return cur + static_cast<ALuint>(al::popcount(sublist.FreeMask)); })};
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
@ -355,7 +356,7 @@ ALbuffer *AllocBuffer(ALCdevice *device)
|
|||||||
);
|
);
|
||||||
|
|
||||||
auto lidx = static_cast<ALuint>(std::distance(device->BufferList.begin(), sublist));
|
auto lidx = static_cast<ALuint>(std::distance(device->BufferList.begin(), sublist));
|
||||||
auto slidx = static_cast<ALuint>(CountTrailingZeros(sublist->FreeMask));
|
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
|
||||||
|
|
||||||
ALbuffer *buffer{::new (sublist->Buffers + slidx) ALbuffer{}};
|
ALbuffer *buffer{::new (sublist->Buffers + slidx) ALbuffer{}};
|
||||||
|
|
||||||
@ -1621,7 +1622,7 @@ BufferSubList::~BufferSubList()
|
|||||||
uint64_t usemask{~FreeMask};
|
uint64_t usemask{~FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
al::destroy_at(Buffers+idx);
|
al::destroy_at(Buffers+idx);
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "AL/efx-presets.h"
|
#include "AL/efx-presets.h"
|
||||||
#include "AL/efx.h"
|
#include "AL/efx.h"
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alcontext.h"
|
#include "alcontext.h"
|
||||||
#include "almalloc.h"
|
#include "almalloc.h"
|
||||||
@ -155,7 +156,7 @@ bool EnsureEffects(ALCdevice *device, size_t needed)
|
|||||||
{
|
{
|
||||||
size_t count{std::accumulate(device->EffectList.cbegin(), device->EffectList.cend(), size_t{0},
|
size_t count{std::accumulate(device->EffectList.cbegin(), device->EffectList.cend(), size_t{0},
|
||||||
[](size_t cur, const EffectSubList &sublist) noexcept -> size_t
|
[](size_t cur, const EffectSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
|
{ return cur + static_cast<ALuint>(al::popcount(sublist.FreeMask)); })};
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
@ -183,7 +184,7 @@ ALeffect *AllocEffect(ALCdevice *device)
|
|||||||
{ return entry.FreeMask != 0; }
|
{ return entry.FreeMask != 0; }
|
||||||
);
|
);
|
||||||
auto lidx = static_cast<ALuint>(std::distance(device->EffectList.begin(), sublist));
|
auto lidx = static_cast<ALuint>(std::distance(device->EffectList.begin(), sublist));
|
||||||
auto slidx = static_cast<ALuint>(CountTrailingZeros(sublist->FreeMask));
|
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
|
||||||
|
|
||||||
ALeffect *effect{::new (sublist->Effects + slidx) ALeffect{}};
|
ALeffect *effect{::new (sublist->Effects + slidx) ALeffect{}};
|
||||||
InitEffectParams(effect, AL_EFFECT_NULL);
|
InitEffectParams(effect, AL_EFFECT_NULL);
|
||||||
@ -543,7 +544,7 @@ EffectSubList::~EffectSubList()
|
|||||||
uint64_t usemask{~FreeMask};
|
uint64_t usemask{~FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
al::destroy_at(Effects+idx);
|
al::destroy_at(Effects+idx);
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "AL/alc.h"
|
#include "AL/alc.h"
|
||||||
#include "AL/efx.h"
|
#include "AL/efx.h"
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alcontext.h"
|
#include "alcontext.h"
|
||||||
#include "almalloc.h"
|
#include "almalloc.h"
|
||||||
@ -324,7 +325,7 @@ bool EnsureFilters(ALCdevice *device, size_t needed)
|
|||||||
{
|
{
|
||||||
size_t count{std::accumulate(device->FilterList.cbegin(), device->FilterList.cend(), size_t{0},
|
size_t count{std::accumulate(device->FilterList.cbegin(), device->FilterList.cend(), size_t{0},
|
||||||
[](size_t cur, const FilterSubList &sublist) noexcept -> size_t
|
[](size_t cur, const FilterSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
|
{ return cur + static_cast<ALuint>(al::popcount(sublist.FreeMask)); })};
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
@ -353,7 +354,7 @@ ALfilter *AllocFilter(ALCdevice *device)
|
|||||||
{ return entry.FreeMask != 0; }
|
{ return entry.FreeMask != 0; }
|
||||||
);
|
);
|
||||||
auto lidx = static_cast<ALuint>(std::distance(device->FilterList.begin(), sublist));
|
auto lidx = static_cast<ALuint>(std::distance(device->FilterList.begin(), sublist));
|
||||||
auto slidx = static_cast<ALuint>(CountTrailingZeros(sublist->FreeMask));
|
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
|
||||||
|
|
||||||
ALfilter *filter{::new(sublist->Filters + slidx) ALfilter{}};
|
ALfilter *filter{::new(sublist->Filters + slidx) ALfilter{}};
|
||||||
InitFilterParams(filter, AL_FILTER_NULL);
|
InitFilterParams(filter, AL_FILTER_NULL);
|
||||||
@ -704,7 +705,7 @@ FilterSubList::~FilterSubList()
|
|||||||
uint64_t usemask{~FreeMask};
|
uint64_t usemask{~FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
al::destroy_at(Filters+idx);
|
al::destroy_at(Filters+idx);
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include "AL/alext.h"
|
#include "AL/alext.h"
|
||||||
#include "AL/efx.h"
|
#include "AL/efx.h"
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alcontext.h"
|
#include "alcontext.h"
|
||||||
#include "almalloc.h"
|
#include "almalloc.h"
|
||||||
@ -684,7 +685,7 @@ bool EnsureSources(ALCcontext *context, size_t needed)
|
|||||||
size_t count{std::accumulate(context->mSourceList.cbegin(), context->mSourceList.cend(),
|
size_t count{std::accumulate(context->mSourceList.cbegin(), context->mSourceList.cend(),
|
||||||
size_t{0},
|
size_t{0},
|
||||||
[](size_t cur, const SourceSubList &sublist) noexcept -> size_t
|
[](size_t cur, const SourceSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<ALuint>(PopCount(sublist.FreeMask)); })};
|
{ return cur + static_cast<ALuint>(al::popcount(sublist.FreeMask)); })};
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
@ -712,7 +713,7 @@ ALsource *AllocSource(ALCcontext *context)
|
|||||||
{ return entry.FreeMask != 0; }
|
{ return entry.FreeMask != 0; }
|
||||||
);
|
);
|
||||||
auto lidx = static_cast<ALuint>(std::distance(context->mSourceList.begin(), sublist));
|
auto lidx = static_cast<ALuint>(std::distance(context->mSourceList.begin(), sublist));
|
||||||
auto slidx = static_cast<ALuint>(CountTrailingZeros(sublist->FreeMask));
|
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
|
||||||
|
|
||||||
ALsource *source{::new(sublist->Sources + slidx) ALsource{}};
|
ALsource *source{::new(sublist->Sources + slidx) ALsource{}};
|
||||||
|
|
||||||
@ -3484,7 +3485,7 @@ SourceSubList::~SourceSubList()
|
|||||||
uint64_t usemask{~FreeMask};
|
uint64_t usemask{~FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const ALsizei idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
al::destroy_at(Sources+idx);
|
al::destroy_at(Sources+idx);
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
}
|
}
|
||||||
|
15
alc/alc.cpp
15
alc/alc.cpp
@ -64,6 +64,7 @@
|
|||||||
#include "al/filter.h"
|
#include "al/filter.h"
|
||||||
#include "al/listener.h"
|
#include "al/listener.h"
|
||||||
#include "al/source.h"
|
#include "al/source.h"
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "albyte.h"
|
#include "albyte.h"
|
||||||
#include "alconfig.h"
|
#include "alconfig.h"
|
||||||
@ -2128,7 +2129,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
|||||||
uint64_t usemask{~sublist.FreeMask};
|
uint64_t usemask{~sublist.FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const int idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
ALeffectslot *slot{sublist.EffectSlots + idx};
|
ALeffectslot *slot{sublist.EffectSlots + idx};
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
|
|
||||||
@ -2149,7 +2150,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const int *attrList)
|
|||||||
uint64_t usemask{~sublist.FreeMask};
|
uint64_t usemask{~sublist.FreeMask};
|
||||||
while(usemask)
|
while(usemask)
|
||||||
{
|
{
|
||||||
const int idx{CountTrailingZeros(usemask)};
|
const int idx{al::countr_zero(usemask)};
|
||||||
ALsource *source{sublist.Sources + idx};
|
ALsource *source{sublist.Sources + idx};
|
||||||
usemask &= ~(1_u64 << idx);
|
usemask &= ~(1_u64 << idx);
|
||||||
|
|
||||||
@ -2292,19 +2293,19 @@ ALCdevice::~ALCdevice()
|
|||||||
|
|
||||||
size_t count{std::accumulate(BufferList.cbegin(), BufferList.cend(), size_t{0u},
|
size_t count{std::accumulate(BufferList.cbegin(), BufferList.cend(), size_t{0u},
|
||||||
[](size_t cur, const BufferSubList &sublist) noexcept -> size_t
|
[](size_t cur, const BufferSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<uint>(PopCount(~sublist.FreeMask)); })};
|
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); })};
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
WARN("%zu Buffer%s not deleted\n", count, (count==1)?"":"s");
|
WARN("%zu Buffer%s not deleted\n", count, (count==1)?"":"s");
|
||||||
|
|
||||||
count = std::accumulate(EffectList.cbegin(), EffectList.cend(), size_t{0u},
|
count = std::accumulate(EffectList.cbegin(), EffectList.cend(), size_t{0u},
|
||||||
[](size_t cur, const EffectSubList &sublist) noexcept -> size_t
|
[](size_t cur, const EffectSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<uint>(PopCount(~sublist.FreeMask)); });
|
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
WARN("%zu Effect%s not deleted\n", count, (count==1)?"":"s");
|
WARN("%zu Effect%s not deleted\n", count, (count==1)?"":"s");
|
||||||
|
|
||||||
count = std::accumulate(FilterList.cbegin(), FilterList.cend(), size_t{0u},
|
count = std::accumulate(FilterList.cbegin(), FilterList.cend(), size_t{0u},
|
||||||
[](size_t cur, const FilterSubList &sublist) noexcept -> size_t
|
[](size_t cur, const FilterSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<uint>(PopCount(~sublist.FreeMask)); });
|
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
WARN("%zu Filter%s not deleted\n", count, (count==1)?"":"s");
|
WARN("%zu Filter%s not deleted\n", count, (count==1)?"":"s");
|
||||||
|
|
||||||
@ -2356,7 +2357,7 @@ ALCcontext::~ALCcontext()
|
|||||||
|
|
||||||
count = std::accumulate(mSourceList.cbegin(), mSourceList.cend(), size_t{0u},
|
count = std::accumulate(mSourceList.cbegin(), mSourceList.cend(), size_t{0u},
|
||||||
[](size_t cur, const SourceSubList &sublist) noexcept -> size_t
|
[](size_t cur, const SourceSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<uint>(PopCount(~sublist.FreeMask)); });
|
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
WARN("%zu Source%s not deleted\n", count, (count==1)?"":"s");
|
WARN("%zu Source%s not deleted\n", count, (count==1)?"":"s");
|
||||||
mSourceList.clear();
|
mSourceList.clear();
|
||||||
@ -2381,7 +2382,7 @@ ALCcontext::~ALCcontext()
|
|||||||
|
|
||||||
count = std::accumulate(mEffectSlotList.cbegin(), mEffectSlotList.cend(), size_t{0u},
|
count = std::accumulate(mEffectSlotList.cbegin(), mEffectSlotList.cend(), size_t{0u},
|
||||||
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
|
[](size_t cur, const EffectSlotSubList &sublist) noexcept -> size_t
|
||||||
{ return cur + static_cast<uint>(PopCount(~sublist.FreeMask)); });
|
{ return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
WARN("%zu AuxiliaryEffectSlot%s not deleted\n", count, (count==1)?"":"s");
|
WARN("%zu AuxiliaryEffectSlot%s not deleted\n", count, (count==1)?"":"s");
|
||||||
mEffectSlotList.clear();
|
mEffectSlotList.clear();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <mmreg.h>
|
#include <mmreg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alnumeric.h"
|
#include "alnumeric.h"
|
||||||
#include "aloptional.h"
|
#include "aloptional.h"
|
||||||
@ -180,7 +181,7 @@ void BackendBase::setChannelOrderFromWFXMask(uint chanmask)
|
|||||||
uint idx{0};
|
uint idx{0};
|
||||||
while(chanmask)
|
while(chanmask)
|
||||||
{
|
{
|
||||||
const int bit{CountTrailingZeros(chanmask)};
|
const int bit{al::countr_zero(chanmask)};
|
||||||
const uint mask{1u << bit};
|
const uint mask{1u << bit};
|
||||||
chanmask &= ~mask;
|
chanmask &= ~mask;
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alcmain.h"
|
#include "alcmain.h"
|
||||||
#include "alu.h"
|
#include "alu.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
@ -1643,7 +1644,7 @@ HRESULT WasapiCapture::resetProxy()
|
|||||||
if((InputType.dwChannelMask&SPEAKER_LOW_FREQUENCY))
|
if((InputType.dwChannelMask&SPEAKER_LOW_FREQUENCY))
|
||||||
{
|
{
|
||||||
constexpr auto lfemask = MaskFromTopBits(SPEAKER_LOW_FREQUENCY);
|
constexpr auto lfemask = MaskFromTopBits(SPEAKER_LOW_FREQUENCY);
|
||||||
const int lfeidx{PopCount(uint32_t{InputType.dwChannelMask&lfemask}) - 1};
|
const int lfeidx{al::popcount(InputType.dwChannelMask&lfemask) - 1};
|
||||||
chanmask &= ~(1u << lfeidx);
|
chanmask &= ~(1u << lfeidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "albyte.h"
|
#include "albyte.h"
|
||||||
#include "alnumeric.h"
|
#include "alnumeric.h"
|
||||||
#include "core/fpu_ctrl.h"
|
#include "core/fpu_ctrl.h"
|
||||||
@ -338,7 +339,7 @@ void ChannelConverter::convert(const void *src, float *dst, uint frames) const
|
|||||||
{
|
{
|
||||||
if(mDstChans == DevFmtMono)
|
if(mDstChans == DevFmtMono)
|
||||||
{
|
{
|
||||||
const float scale{std::sqrt(1.0f / static_cast<float>(PopCount(mChanMask)))};
|
const float scale{std::sqrt(1.0f / static_cast<float>(al::popcount(mChanMask)))};
|
||||||
switch(mSrcType)
|
switch(mSrcType)
|
||||||
{
|
{
|
||||||
#define HANDLE_FMT(T) case T: Multi2Mono<T>(mChanMask, mSrcStep, scale, dst, src, frames); break
|
#define HANDLE_FMT(T) case T: Multi2Mono<T>(mChanMask, mSrcStep, scale, dst, src, frames); break
|
||||||
|
108
common/albit.h
108
common/albit.h
@ -1,6 +1,12 @@
|
|||||||
#ifndef AL_BIT_H
|
#ifndef AL_BIT_H
|
||||||
#define AL_BIT_H
|
#define AL_BIT_H
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <type_traits>
|
||||||
|
#if !defined(__GNUC__) && (defined(_WIN32) || defined(_WIN64))
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace al {
|
namespace al {
|
||||||
|
|
||||||
#ifdef __BYTE_ORDER__
|
#ifdef __BYTE_ORDER__
|
||||||
@ -30,6 +36,108 @@ enum class endian {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Define popcount (population count/count 1 bits) and countr_zero (count
|
||||||
|
* trailing zero bits, starting from the lsb) methods, for various integer
|
||||||
|
* types.
|
||||||
|
*/
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
namespace detail_ {
|
||||||
|
inline int popcount(unsigned long long val) noexcept { return __builtin_popcountll(val); }
|
||||||
|
inline int popcount(unsigned long val) noexcept { return __builtin_popcountl(val); }
|
||||||
|
inline int popcount(unsigned int val) noexcept { return __builtin_popcount(val); }
|
||||||
|
|
||||||
|
inline int countr_zero(unsigned long long val) noexcept { return __builtin_ctzll(val); }
|
||||||
|
inline int countr_zero(unsigned long val) noexcept { return __builtin_ctzl(val); }
|
||||||
|
inline int countr_zero(unsigned int val) noexcept { return __builtin_ctz(val); }
|
||||||
|
} // namespace detail_
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> popcount(T v) noexcept { return detail_::popcount(v); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> countr_zero(T val) noexcept
|
||||||
|
{ return val ? detail_::countr_zero(val) : std::numeric_limits<T>::digits; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* There be black magics here. The popcount method is derived from
|
||||||
|
* https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
||||||
|
* while the ctz-utilizing-popcount algorithm is shown here
|
||||||
|
* http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
|
||||||
|
* as the ntz2 variant. These likely aren't the most efficient methods, but
|
||||||
|
* they're good enough if the GCC built-ins aren't available.
|
||||||
|
*/
|
||||||
|
namespace detail_ {
|
||||||
|
template<typename T>
|
||||||
|
constexpr T repbits(unsigned char bits) noexcept
|
||||||
|
{
|
||||||
|
T ret{bits};
|
||||||
|
for(size_t i{1};i < sizeof(T);++i)
|
||||||
|
ret = (ret<<8) | bits;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // namespace detail_
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> popcount(T v) noexcept
|
||||||
|
{
|
||||||
|
constexpr T m55{detail_::repbits<T>(0x55)};
|
||||||
|
constexpr T m33{detail_::repbits<T>(0x33)};
|
||||||
|
constexpr T m0f{detail_::repbits<T>(0x0f)};
|
||||||
|
constexpr T m01{detail_::repbits<T>(0x01)};
|
||||||
|
|
||||||
|
v = v - ((v >> 1) & m55);
|
||||||
|
v = (v & m33) + ((v >> 2) & m33);
|
||||||
|
v = (v + (v >> 4)) & m0f;
|
||||||
|
return static_cast<int>((v * m01) >> ((sizeof(T)-1)*8));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN64)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> countr_zero(T v)
|
||||||
|
{
|
||||||
|
unsigned long idx{std::numeric_limits<T>::digits};
|
||||||
|
if /*constexpr*/(std::numeric_limits<T>::digits <= 32)
|
||||||
|
_BitScanForward(&idx, static_cast<uint32_t>(v));
|
||||||
|
else // std::numeric_limits<T>::digits > 32
|
||||||
|
_BitScanForward64(&idx, v);
|
||||||
|
return static_cast<int>(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> countr_zero(T v)
|
||||||
|
{
|
||||||
|
unsigned long idx{std::numeric_limits<T>::digits};
|
||||||
|
if /*constexpr*/(std::numeric_limits<T>::digits <= 32)
|
||||||
|
_BitScanForward(&idx, static_cast<uint32_t>(v));
|
||||||
|
else if(!_BitScanForward(&idx, static_cast<uint32_t>(v)))
|
||||||
|
{
|
||||||
|
if(_BitScanForward(&idx, static_cast<uint32_t>(v>>32)))
|
||||||
|
idx += 32;
|
||||||
|
}
|
||||||
|
return static_cast<int>(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr std::enable_if_t<std::is_integral<T>::value && std::is_unsigned<T>::value,
|
||||||
|
int> countr_zero(T value)
|
||||||
|
{ return popcount(static_cast<T>(~value & (value - 1))); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace al
|
} // namespace al
|
||||||
|
|
||||||
#endif /* AL_BIT_H */
|
#endif /* AL_BIT_H */
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "albit.h"
|
||||||
#include "alnumeric.h"
|
#include "alnumeric.h"
|
||||||
#include "math_defs.h"
|
#include "math_defs.h"
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ void complex_fft(const al::span<std::complex<double>> buffer, const double sign)
|
|||||||
/* Get the number of bits used for indexing. Simplifies bit-reversal and
|
/* Get the number of bits used for indexing. Simplifies bit-reversal and
|
||||||
* the main loop count.
|
* the main loop count.
|
||||||
*/
|
*/
|
||||||
const size_t log2_size{static_cast<size_t>(CountTrailingZeros(fftsize))};
|
const size_t log2_size{static_cast<size_t>(al::countr_zero(fftsize))};
|
||||||
|
|
||||||
/* Bit-reversal permutation applied to a sequence of fftsize items. */
|
/* Bit-reversal permutation applied to a sequence of fftsize items. */
|
||||||
for(size_t idx{1u};idx < fftsize-1;++idx)
|
for(size_t idx{1u};idx < fftsize-1;++idx)
|
||||||
|
@ -103,92 +103,6 @@ inline size_t RoundUp(size_t value, size_t r) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Define CountTrailingZeros (count trailing zero bits, starting from the lsb)
|
|
||||||
* and PopCount (population count/count 1 bits) methods, for 32- and 64-bit
|
|
||||||
* integers. The CountTrailingZeros results are *UNDEFINED* if the value is 0.
|
|
||||||
*/
|
|
||||||
#ifdef __GNUC__
|
|
||||||
|
|
||||||
/* Define variations for unsigned (long (long)) int, since we don't know what
|
|
||||||
* uint32/64_t are typedef'd to.
|
|
||||||
*/
|
|
||||||
inline int PopCount(unsigned long long val) { return __builtin_popcountll(val); }
|
|
||||||
inline int PopCount(unsigned long val) { return __builtin_popcountl(val); }
|
|
||||||
inline int PopCount(unsigned int val) { return __builtin_popcount(val); }
|
|
||||||
|
|
||||||
inline int CountTrailingZeros(unsigned long long val) { return __builtin_ctzll(val); }
|
|
||||||
inline int CountTrailingZeros(unsigned long val) { return __builtin_ctzl(val); }
|
|
||||||
inline int CountTrailingZeros(unsigned int val) { return __builtin_ctz(val); }
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* There be black magics here. The popcnt method is derived from
|
|
||||||
* https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
|
||||||
* while the ctz-utilizing-popcnt algorithm is shown here
|
|
||||||
* http://www.hackersdelight.org/hdcodetxt/ntz.c.txt
|
|
||||||
* as the ntz2 variant. These likely aren't the most efficient methods, but
|
|
||||||
* they're good enough if the GCC built-ins aren't available.
|
|
||||||
*/
|
|
||||||
inline int PopCount(uint32_t v)
|
|
||||||
{
|
|
||||||
v = v - ((v >> 1) & 0x55555555u);
|
|
||||||
v = (v & 0x33333333u) + ((v >> 2) & 0x33333333u);
|
|
||||||
v = (v + (v >> 4)) & 0x0f0f0f0fu;
|
|
||||||
return static_cast<int>((v * 0x01010101u) >> 24);
|
|
||||||
}
|
|
||||||
inline int PopCount(uint64_t v)
|
|
||||||
{
|
|
||||||
v = v - ((v >> 1) & 0x5555555555555555_u64);
|
|
||||||
v = (v & 0x3333333333333333_u64) + ((v >> 2) & 0x3333333333333333_u64);
|
|
||||||
v = (v + (v >> 4)) & 0x0f0f0f0f0f0f0f0f_u64;
|
|
||||||
return static_cast<int>((v * 0x0101010101010101_u64) >> 56);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_WIN64)
|
|
||||||
|
|
||||||
inline int CountTrailingZeros(uint32_t v)
|
|
||||||
{
|
|
||||||
unsigned long idx = 32;
|
|
||||||
_BitScanForward(&idx, v);
|
|
||||||
return static_cast<int>(idx);
|
|
||||||
}
|
|
||||||
inline int CountTrailingZeros(uint64_t v)
|
|
||||||
{
|
|
||||||
unsigned long idx = 64;
|
|
||||||
_BitScanForward64(&idx, v);
|
|
||||||
return static_cast<int>(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
|
|
||||||
inline int CountTrailingZeros(uint32_t v)
|
|
||||||
{
|
|
||||||
unsigned long idx = 32;
|
|
||||||
_BitScanForward(&idx, v);
|
|
||||||
return static_cast<int>(idx);
|
|
||||||
}
|
|
||||||
inline int CountTrailingZeros(uint64_t v)
|
|
||||||
{
|
|
||||||
unsigned long idx = 64;
|
|
||||||
if(!_BitScanForward(&idx, static_cast<uint32_t>(v&0xffffffff)))
|
|
||||||
{
|
|
||||||
if(_BitScanForward(&idx, static_cast<uint32_t>(v>>32)))
|
|
||||||
idx += 32;
|
|
||||||
}
|
|
||||||
return static_cast<int>(idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
inline int CountTrailingZeros(uint32_t value)
|
|
||||||
{ return PopCount(~value & (value - 1)); }
|
|
||||||
inline int CountTrailingZeros(uint64_t value)
|
|
||||||
{ return PopCount(~value & (value - 1)); }
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fast float-to-int conversion. No particular rounding mode is assumed; the
|
* Fast float-to-int conversion. No particular rounding mode is assumed; the
|
||||||
* IEEE-754 default is round-to-nearest with ties-to-even, though an app could
|
* IEEE-754 default is round-to-nearest with ties-to-even, though an app could
|
||||||
|
Loading…
x
Reference in New Issue
Block a user