Use a flexible array for HrtfHandle and SampleConverter

This commit is contained in:
Chris Robinson 2019-01-11 22:09:57 -08:00
parent f8c2e54b47
commit ab16671466
3 changed files with 47 additions and 31 deletions

View File

@ -141,11 +141,10 @@ SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType,
if(numchans <= 0 || srcRate <= 0 || dstRate <= 0)
return nullptr;
const size_t alloc_size{FAM_SIZE(SampleConverter, mChan, numchans)};
SampleConverterPtr converter{new (al_calloc(16, alloc_size)) SampleConverter{}};
void *ptr{al_calloc(16, SampleConverter::Sizeof(numchans))};
SampleConverterPtr converter{new (ptr) SampleConverter{static_cast<size_t>(numchans)}};
converter->mSrcType = srcType;
converter->mDstType = dstType;
converter->mNumChannels = numchans;
converter->mSrcTypeSize = BytesFromDevFmt(srcType);
converter->mDstTypeSize = BytesFromDevFmt(dstType);
@ -208,8 +207,8 @@ ALsizei SampleConverter::availableOut(ALsizei srcframes) const
ALsizei SampleConverter::convert(const ALvoid **src, ALsizei *srcframes, ALvoid *dst, ALsizei dstframes)
{
const ALsizei SrcFrameSize{mNumChannels * mSrcTypeSize};
const ALsizei DstFrameSize{mNumChannels * mDstTypeSize};
const ALsizei SrcFrameSize{static_cast<ALsizei>(mChan.size()) * mSrcTypeSize};
const ALsizei DstFrameSize{static_cast<ALsizei>(mChan.size()) * mDstTypeSize};
const ALsizei increment{mIncrement};
auto SamplesIn = static_cast<const ALbyte*>(*src);
ALsizei NumSrcSamples{*srcframes};
@ -241,9 +240,9 @@ ALsizei SampleConverter::convert(const ALvoid **src, ALsizei *srcframes, ALvoid
/* Not enough input samples to generate an output sample. Store
* what we're given for later.
*/
for(ALsizei chan{0};chan < mNumChannels;chan++)
for(size_t chan{0u};chan < mChan.size();chan++)
LoadSamples(&mChan[chan].PrevSamples[prepcount], SamplesIn + mSrcTypeSize*chan,
mNumChannels, mSrcType, toread);
mChan.size(), mSrcType, toread);
mSrcPrepCount = prepcount + toread;
NumSrcSamples = 0;
@ -264,7 +263,7 @@ ALsizei SampleConverter::convert(const ALvoid **src, ALsizei *srcframes, ALvoid
clampu64((DataSize64 + increment-1)/increment, 1, BUFFERSIZE));
DstSize = mini(DstSize, dstframes-pos);
for(ALsizei chan{0};chan < mNumChannels;chan++)
for(size_t chan{0u};chan < mChan.size();chan++)
{
const ALbyte *SrcSamples = SamplesIn + mSrcTypeSize*chan;
ALbyte *DstSamples = static_cast<ALbyte*>(dst) + mDstTypeSize*chan;
@ -273,7 +272,7 @@ ALsizei SampleConverter::convert(const ALvoid **src, ALsizei *srcframes, ALvoid
* new samples from the input buffer.
*/
std::copy_n(mChan[chan].PrevSamples, prepcount, SrcData);
LoadSamples(SrcData + prepcount, SrcSamples, mNumChannels, mSrcType, toread);
LoadSamples(SrcData + prepcount, SrcSamples, mChan.size(), mSrcType, toread);
/* Store as many prep samples for next time as possible, given the
* number of output samples being generated.
@ -294,7 +293,7 @@ ALsizei SampleConverter::convert(const ALvoid **src, ALsizei *srcframes, ALvoid
const ALfloat *ResampledData{mResample(&mState, SrcData+MAX_RESAMPLE_PADDING,
DataPosFrac, increment, DstData, DstSize)};
StoreSamples(DstSamples, ResampledData, mNumChannels, mDstType, DstSize);
StoreSamples(DstSamples, ResampledData, mChan.size(), mDstType, DstSize);
}
/* Update the number of prep samples still available, as well as the

View File

@ -10,7 +10,6 @@
struct SampleConverter {
DevFmtType mSrcType{};
DevFmtType mDstType{};
ALsizei mNumChannels{};
ALsizei mSrcTypeSize{};
ALsizei mDstTypeSize{};
@ -24,13 +23,24 @@ struct SampleConverter {
alignas(16) ALfloat mSrcSamples[BUFFERSIZE]{};
alignas(16) ALfloat mDstSamples[BUFFERSIZE]{};
struct {
struct ChanSamples {
alignas(16) ALfloat PrevSamples[MAX_RESAMPLE_PADDING*2];
} mChan[];
};
al::FlexArray<ChanSamples> mChan;
SampleConverter(size_t numchans) : mChan{numchans} { }
SampleConverter(const SampleConverter&) = delete;
SampleConverter& operator=(const SampleConverter&) = delete;
ALsizei convert(const ALvoid **src, ALsizei *srcframes, ALvoid *dst, ALsizei dstframes);
ALsizei availableOut(ALsizei srcframes) const;
static constexpr size_t Sizeof(size_t length) noexcept
{
return maxz(sizeof(SampleConverter),
al::FlexArray<ChanSamples>::Sizeof(length, offsetof(SampleConverter, mChan)));
}
DEF_PLACE_NEWDEL()
};
using SampleConverterPtr = std::unique_ptr<SampleConverter>;

View File

@ -45,17 +45,26 @@
struct HrtfHandle {
HrtfEntry *entry{nullptr};
char filename[];
al::FlexArray<char> filename;
HrtfHandle(size_t fname_len) : filename{fname_len} { }
HrtfHandle(const HrtfHandle&) = delete;
HrtfHandle& operator=(const HrtfHandle&) = delete;
static std::unique_ptr<HrtfHandle> Create(size_t fname_len);
static constexpr size_t Sizeof(size_t length) noexcept
{
return maxz(sizeof(HrtfHandle),
al::FlexArray<char>::Sizeof(length, offsetof(HrtfHandle, filename)));
}
DEF_PLACE_NEWDEL()
};
std::unique_ptr<HrtfHandle> HrtfHandle::Create(size_t fname_len)
{
void *ptr{al_calloc(DEF_ALIGN, FAM_SIZE(HrtfHandle, filename, fname_len))};
return std::unique_ptr<HrtfHandle>{new (ptr) HrtfHandle{}};
void *ptr{al_calloc(DEF_ALIGN, HrtfHandle::Sizeof(fname_len))};
return std::unique_ptr<HrtfHandle>{new (ptr) HrtfHandle{fname_len}};
}
namespace {
@ -973,7 +982,7 @@ void AddFileEntry(al::vector<EnumeratedHrtf> &list, const std::string &filename)
auto loaded_entry = LoadedHrtfs.begin();
for(;loaded_entry != LoadedHrtfs.end();++loaded_entry)
{
if(filename != (*loaded_entry)->filename)
if(filename != (*loaded_entry)->filename.data())
continue;
/* Check if this entry has already been added to the list. */
@ -996,7 +1005,7 @@ void AddFileEntry(al::vector<EnumeratedHrtf> &list, const std::string &filename)
LoadedHrtfs.emplace_back(HrtfHandle::Create(filename.length()+1));
loaded_entry = LoadedHrtfs.end()-1;
strcpy((*loaded_entry)->filename, filename.c_str());
strcpy((*loaded_entry)->filename.data(), filename.c_str());
}
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a
@ -1031,7 +1040,7 @@ void AddBuiltInEntry(al::vector<EnumeratedHrtf> &list, const std::string &filena
auto loaded_entry = LoadedHrtfs.begin();
for(;loaded_entry != LoadedHrtfs.end();++loaded_entry)
{
if(filename != (*loaded_entry)->filename)
if(filename != (*loaded_entry)->filename.data())
continue;
/* Check if this entry has already been added to the list. */
@ -1050,14 +1059,12 @@ void AddBuiltInEntry(al::vector<EnumeratedHrtf> &list, const std::string &filena
if(loaded_entry == LoadedHrtfs.end())
{
const size_t namelen{filename.length()+32};
TRACE("Got new file \"%s\"\n", filename.c_str());
LoadedHrtfs.emplace_back(HrtfHandle::Create(namelen));
LoadedHrtfs.emplace_back(HrtfHandle::Create(filename.length()+32));
loaded_entry = LoadedHrtfs.end()-1;
snprintf((*loaded_entry)->filename, namelen, "!%u_%s",
residx, filename.c_str());
snprintf((*loaded_entry)->filename.data(), (*loaded_entry)->filename.size(), "!%u_%s",
residx, filename.c_str());
}
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a
@ -1195,9 +1202,9 @@ HrtfEntry *GetLoadedHrtf(HrtfHandle *handle)
const char *name{""};
ALuint residx{};
char ch{};
if(sscanf(handle->filename, "!%u%c", &residx, &ch) == 2 && ch == '_')
if(sscanf(handle->filename.data(), "!%u%c", &residx, &ch) == 2 && ch == '_')
{
name = strchr(handle->filename, ch)+1;
name = strchr(handle->filename.data(), ch)+1;
TRACE("Loading %s...\n", name);
ResData res{GetResource(residx)};
@ -1210,13 +1217,13 @@ HrtfEntry *GetLoadedHrtf(HrtfHandle *handle)
}
else
{
name = handle->filename;
name = handle->filename.data();
TRACE("Loading %s...\n", handle->filename);
auto fstr = al::make_unique<al::ifstream>(handle->filename, std::ios::binary);
TRACE("Loading %s...\n", handle->filename.data());
auto fstr = al::make_unique<al::ifstream>(handle->filename.data(), std::ios::binary);
if(!fstr->is_open())
{
ERR("Could not open %s\n", handle->filename);
ERR("Could not open %s\n", handle->filename.data());
return nullptr;
}
stream = std::move(fstr);
@ -1286,7 +1293,7 @@ void Hrtf_DecRef(HrtfEntry *hrtf)
{
al_free((*iter)->entry);
(*iter)->entry = nullptr;
TRACE("Unloaded unused HRTF %s\n", (*iter)->filename);
TRACE("Unloaded unused HRTF %s\n", (*iter)->filename.data());
}
}
}