Initial commit

added libraries:
opus
flac
libsndfile

updated:
libvorbis
libogg
openal

- Everything works as expected for now. Bare in mind libsndfile needed the check for whether or not it could find the xiph libraries removed in order for this to work.
This commit is contained in:
marauder2k7 2024-03-21 17:33:47 +00:00
parent 05a083ca6f
commit a745fc3757
1954 changed files with 431332 additions and 21037 deletions

View file

@ -37,8 +37,11 @@
#include <vector>
#include "alfstream.h"
#include "aloptional.h"
#include "alspan.h"
#include "alstring.h"
#include "makemhr.h"
#include "polyphase_resampler.h"
#include "mysofa.h"
@ -1236,7 +1239,8 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
double distances[MAX_FD_COUNT];
uint fdCount = 0;
uint evCounts[MAX_FD_COUNT];
std::vector<uint> azCounts(MAX_FD_COUNT * MAX_EV_COUNT);
auto azCounts = std::vector<std::array<uint,MAX_EV_COUNT>>(MAX_FD_COUNT);
for(auto &azs : azCounts) azs.fill(0u);
TrIndication(tr, &line, &col);
while(TrIsIdent(tr))
@ -1385,7 +1389,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
{
if(!TrReadInt(tr, MIN_AZ_COUNT, MAX_AZ_COUNT, &intVal))
return 0;
azCounts[(count * MAX_EV_COUNT) + evCounts[count]++] = static_cast<uint>(intVal);
azCounts[count][evCounts[count]++] = static_cast<uint>(intVal);
if(TrIsOperator(tr, ","))
{
if(evCounts[count] >= MAX_EV_COUNT)
@ -1402,7 +1406,7 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
TrErrorAt(tr, line, col, "Did not reach the minimum of %d azimuth counts.\n", MIN_EV_COUNT);
return 0;
}
if(azCounts[count * MAX_EV_COUNT] != 1 || azCounts[(count * MAX_EV_COUNT) + evCounts[count] - 1] != 1)
if(azCounts[count][0] != 1 || azCounts[count][evCounts[count] - 1] != 1)
{
TrError(tr, "Poles are not singular for field %d.\n", count - 1);
return 0;
@ -1447,7 +1451,8 @@ static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint trunc
}
if(hData->mChannelType == CT_NONE)
hData->mChannelType = CT_MONO;
if(!PrepareHrirData(fdCount, distances, evCounts, azCounts.data(), hData))
const auto azs = al::as_span(azCounts).first<MAX_FD_COUNT>();
if(!PrepareHrirData({distances, fdCount}, evCounts, azs, hData))
{
fprintf(stderr, "Error: Out of memory.\n");
exit(-1);
@ -1460,9 +1465,9 @@ static int ReadIndexTriplet(TokenReaderT *tr, const HrirDataT *hData, uint *fi,
{
int intVal;
if(hData->mFdCount > 1)
if(hData->mFds.size() > 1)
{
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFdCount) - 1, &intVal))
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFds.size()-1), &intVal))
return 0;
*fi = static_cast<uint>(intVal);
if(!TrReadOperator(tr, ","))
@ -1472,12 +1477,12 @@ static int ReadIndexTriplet(TokenReaderT *tr, const HrirDataT *hData, uint *fi,
{
*fi = 0;
}
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFds[*fi].mEvCount) - 1, &intVal))
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFds[*fi].mEvs.size()-1), &intVal))
return 0;
*ei = static_cast<uint>(intVal);
if(!TrReadOperator(tr, ","))
return 0;
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFds[*fi].mEvs[*ei].mAzCount) - 1, &intVal))
if(!TrReadInt(tr, 0, static_cast<int>(hData->mFds[*fi].mEvs[*ei].mAzs.size()-1), &intVal))
return 0;
*ai = static_cast<uint>(intVal);
return 1;
@ -1707,14 +1712,11 @@ static int MatchTargetEar(const char *ident)
// Calculate the onset time of an HRIR and average it with any existing
// timing for its field, elevation, azimuth, and ear.
static double AverageHrirOnset(const uint rate, const uint n, const double *hrir, const double f, const double onset)
static constexpr int OnsetRateMultiple{10};
static double AverageHrirOnset(PPhaseResampler &rs, al::span<double> upsampled, const uint rate,
const uint n, const double *hrir, const double f, const double onset)
{
std::vector<double> upsampled(10 * n);
{
PPhaseResampler rs;
rs.init(rate, 10 * rate);
rs.process(n, hrir, 10 * n, upsampled.data());
}
rs.process(n, hrir, static_cast<uint>(upsampled.size()), upsampled.data());
auto abs_lt = [](const double &lhs, const double &rhs) -> bool
{ return std::abs(lhs) < std::abs(rhs); };
@ -1731,9 +1733,9 @@ static void AverageHrirMagnitude(const uint points, const uint n, const double *
std::vector<double> r(n);
for(i = 0;i < points;i++)
h[i] = complex_d{hrir[i], 0.0};
h[i] = hrir[i];
for(;i < n;i++)
h[i] = complex_d{0.0, 0.0};
h[i] = 0.0;
FftForward(n, h.data());
MagnitudeResponse(n, h.data(), r.data());
for(i = 0;i < m;i++)
@ -1741,18 +1743,29 @@ static void AverageHrirMagnitude(const uint points, const uint n, const double *
}
// Process the list of sources in the data set definition.
static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
static int ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate)
{
uint channels = (hData->mChannelType == CT_STEREO) ? 2 : 1;
const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
double *hrirs = hData->mHrirsBase.data();
std::vector<double> hrir(hData->mIrPoints);
auto hrir = std::make_unique<double[]>(hData->mIrSize);
uint line, col, fi, ei, ai;
int count;
std::vector<double> onsetSamples(OnsetRateMultiple * hData->mIrPoints);
PPhaseResampler onsetResampler;
onsetResampler.init(hData->mIrRate, OnsetRateMultiple*hData->mIrRate);
al::optional<PPhaseResampler> resampler;
if(outRate && outRate != hData->mIrRate)
resampler.emplace().init(hData->mIrRate, outRate);
const double rateScale{outRate ? static_cast<double>(outRate) / hData->mIrRate : 1.0};
const uint irPoints{outRate
? std::min(static_cast<uint>(std::ceil(hData->mIrPoints*rateScale)), hData->mIrPoints)
: hData->mIrPoints};
printf("Loading sources...");
fflush(stdout);
count = 0;
int count{0};
while(TrIsOperator(tr, "["))
{
double factor[2]{ 1.0, 1.0 };
@ -1834,45 +1847,53 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
else
aer[0] = std::fmod(360.0f - aer[0], 360.0f);
for(fi = 0;fi < hData->mFdCount;fi++)
{
double delta = aer[2] - hData->mFds[fi].mDistance;
if(std::abs(delta) < 0.001) break;
}
if(fi >= hData->mFdCount)
auto field = std::find_if(hData->mFds.cbegin(), hData->mFds.cend(),
[&aer](const HrirFdT &fld) -> bool
{ return (std::abs(aer[2] - fld.mDistance) < 0.001); });
if(field == hData->mFds.cend())
continue;
fi = static_cast<uint>(std::distance(hData->mFds.cbegin(), field));
double ef{(90.0 + aer[1]) / 180.0 * (hData->mFds[fi].mEvCount - 1)};
const double evscale{180.0 / static_cast<double>(field->mEvs.size()-1)};
double ef{(90.0 + aer[1]) / evscale};
ei = static_cast<uint>(std::round(ef));
ef = (ef - ei) * 180.0 / (hData->mFds[fi].mEvCount - 1);
ef = (ef - ei) * evscale;
if(std::abs(ef) >= 0.1)
continue;
double af{aer[0] / 360.0 * hData->mFds[fi].mEvs[ei].mAzCount};
const double azscale{360.0 / static_cast<double>(field->mEvs[ei].mAzs.size())};
double af{aer[0] / azscale};
ai = static_cast<uint>(std::round(af));
af = (af - ai) * 360.0 / hData->mFds[fi].mEvs[ei].mAzCount;
ai = ai % hData->mFds[fi].mEvs[ei].mAzCount;
af = (af - ai) * azscale;
ai %= static_cast<uint>(field->mEvs[ei].mAzs.size());
if(std::abs(af) >= 0.1)
continue;
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
HrirAzT *azd = &field->mEvs[ei].mAzs[ai];
if(azd->mIrs[0] != nullptr)
{
TrErrorAt(tr, line, col, "Redefinition of source [ %d, %d, %d ].\n", fi, ei, ai);
return 0;
}
ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.data());
ExtractSofaHrir(sofa, si, 0, src.mOffset, hData->mIrPoints, hrir.get());
azd->mIrs[0] = &hrirs[hData->mIrSize * azd->mIndex];
azd->mDelays[0] = AverageHrirOnset(hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[0]);
AverageHrirMagnitude(hData->mIrPoints, hData->mFftSize, hrir.data(), 1.0, azd->mIrs[0]);
azd->mDelays[0] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[0]);
if(resampler)
resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[0]);
if(src.mChannel == 1)
{
ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.data());
ExtractSofaHrir(sofa, si, 1, src.mOffset, hData->mIrPoints, hrir.get());
azd->mIrs[1] = &hrirs[hData->mIrSize * (hData->mIrCount + azd->mIndex)];
azd->mDelays[1] = AverageHrirOnset(hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0, azd->mDelays[1]);
AverageHrirMagnitude(hData->mIrPoints, hData->mFftSize, hrir.data(), 1.0, azd->mIrs[1]);
azd->mDelays[1] = AverageHrirOnset(onsetResampler, onsetSamples,
hData->mIrRate, hData->mIrPoints, hrir.get(), 1.0, azd->mDelays[1]);
if(resampler)
resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize,
hrir.get());
AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0, azd->mIrs[1]);
}
// TODO: Since some SOFA files contain minimum phase HRIRs,
@ -1911,7 +1932,7 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
printf("\rLoading sources... %d file%s", count, (count==1)?"":"s");
fflush(stdout);
if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.data()))
if(!LoadSource(&src, hData->mIrRate, hData->mIrPoints, hrir.get()))
return 0;
uint ti{0};
@ -1929,8 +1950,12 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
}
}
azd->mIrs[ti] = &hrirs[hData->mIrSize * (ti * hData->mIrCount + azd->mIndex)];
azd->mDelays[ti] = AverageHrirOnset(hData->mIrRate, hData->mIrPoints, hrir.data(), 1.0 / factor[ti], azd->mDelays[ti]);
AverageHrirMagnitude(hData->mIrPoints, hData->mFftSize, hrir.data(), 1.0 / factor[ti], azd->mIrs[ti]);
azd->mDelays[ti] = AverageHrirOnset(onsetResampler, onsetSamples, hData->mIrRate,
hData->mIrPoints, hrir.get(), 1.0 / factor[ti], azd->mDelays[ti]);
if(resampler)
resampler->process(hData->mIrPoints, hrir.get(), hData->mIrSize, hrir.get());
AverageHrirMagnitude(irPoints, hData->mFftSize, hrir.get(), 1.0 / factor[ti],
azd->mIrs[ti]);
factor[ti] += 1.0;
if(!TrIsOperator(tr, "+"))
break;
@ -1951,28 +1976,35 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
}
}
printf("\n");
for(fi = 0;fi < hData->mFdCount;fi++)
hrir = nullptr;
if(resampler)
{
for(ei = 0;ei < hData->mFds[fi].mEvCount;ei++)
hData->mIrRate = outRate;
hData->mIrPoints = irPoints;
resampler.reset();
}
for(fi = 0;fi < hData->mFds.size();fi++)
{
for(ei = 0;ei < hData->mFds[fi].mEvs.size();ei++)
{
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzCount;ai++)
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
if(azd->mIrs[0] != nullptr)
break;
}
if(ai < hData->mFds[fi].mEvs[ei].mAzCount)
if(ai < hData->mFds[fi].mEvs[ei].mAzs.size())
break;
}
if(ei >= hData->mFds[fi].mEvCount)
if(ei >= hData->mFds[fi].mEvs.size())
{
TrError(tr, "Missing source references [ %d, *, * ].\n", fi);
return 0;
}
hData->mFds[fi].mEvStart = ei;
for(;ei < hData->mFds[fi].mEvCount;ei++)
for(;ei < hData->mFds[fi].mEvs.size();ei++)
{
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzCount;ai++)
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
@ -1986,11 +2018,11 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
}
for(uint ti{0};ti < channels;ti++)
{
for(fi = 0;fi < hData->mFdCount;fi++)
for(fi = 0;fi < hData->mFds.size();fi++)
{
for(ei = 0;ei < hData->mFds[fi].mEvCount;ei++)
for(ei = 0;ei < hData->mFds[fi].mEvs.size();ei++)
{
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzCount;ai++)
for(ai = 0;ai < hData->mFds[fi].mEvs[ei].mAzs.size();ai++)
{
HrirAzT *azd = &hData->mFds[fi].mEvs[ei].mAzs[ai];
@ -2012,14 +2044,14 @@ static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
bool LoadDefInput(std::istream &istream, const char *startbytes, std::streamsize startbytecount,
const char *filename, const uint fftSize, const uint truncSize, const ChannelModeT chanMode,
HrirDataT *hData)
const char *filename, const uint fftSize, const uint truncSize, const uint outRate,
const ChannelModeT chanMode, HrirDataT *hData)
{
TokenReaderT tr{istream};
TrSetup(startbytes, startbytecount, filename, &tr);
if(!ProcessMetrics(&tr, fftSize, truncSize, chanMode, hData)
|| !ProcessSources(&tr, hData))
|| !ProcessSources(&tr, hData, outRate))
return false;
return true;