Use a flexible array for HrtfHandle and SampleConverter
This commit is contained in:
parent
f8c2e54b47
commit
ab16671466
@ -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
|
||||
|
@ -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>;
|
||||
|
43
Alc/hrtf.cpp
43
Alc/hrtf.cpp
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user