Skip to content

Commit

Permalink
Merge branch 'kcat:master' into utils
Browse files Browse the repository at this point in the history
  • Loading branch information
ThreeDeeJay authored Aug 4, 2024
2 parents 93e378f + a3eb863 commit 3e1e002
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 26 deletions.
6 changes: 5 additions & 1 deletion alc/panning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1198,21 +1198,25 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, std::optional<StereoEncodin

if(stereomode.value_or(StereoEncoding::Default) == StereoEncoding::Uhj)
{
auto ftype = std::string_view{};
switch(UhjEncodeQuality)
{
case UhjQualityType::IIR:
device->mUhjEncoder = std::make_unique<UhjEncoderIIR>();
ftype = "IIR"sv;
break;
case UhjQualityType::FIR256:
device->mUhjEncoder = std::make_unique<UhjEncoder<UhjLength256>>();
ftype = "FIR-256"sv;
break;
case UhjQualityType::FIR512:
device->mUhjEncoder = std::make_unique<UhjEncoder<UhjLength512>>();
ftype = "FIR-512"sv;
break;
}
assert(device->mUhjEncoder != nullptr);

TRACE("UHJ enabled\n");
TRACE("UHJ enabled (%.*s encoder)\n", al::sizei(ftype), ftype.data());
InitUhjPanning(device);
device->PostProcess = &ALCdevice::ProcessUhj;
return;
Expand Down
96 changes: 73 additions & 23 deletions examples/allafplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
#include "AL/al.h"
#include "AL/alext.h"

#include "alassert.h"
#include "albit.h"
#include "almalloc.h"
#include "alnumeric.h"
Expand All @@ -115,6 +114,25 @@ namespace {
namespace fs = std::filesystem;
using namespace std::string_view_literals;

[[noreturn]]
void do_assert(const char *message, int linenum, const char *filename, const char *funcname)
{
auto errstr = std::string{filename};
errstr += ':';
errstr += std::to_string(linenum);
errstr += ": ";
errstr += funcname;
errstr += ": ";
errstr += message;
throw std::runtime_error{errstr};
}

#define MyAssert(cond) do { \
if(!(cond)) UNLIKELY \
do_assert("Assertion '" #cond "' failed", __LINE__, __FILE__, \
std::data(__func__)); \
} while(0)


enum class Quality : std::uint8_t {
s8, s16, f32, s24
Expand Down Expand Up @@ -325,15 +343,22 @@ auto LafStream::readChunk() -> uint32_t
{ return val + unsigned(al::popcount(unsigned(in))); });

/* Make sure enable bits aren't set for non-existent tracks. */
alassert(mEnabledTracks[((mNumTracks+7_uz)>>3) - 1] < (1u<<(mNumTracks&7)));
if(mEnabledTracks[((mNumTracks+7_uz)>>3) - 1] >= (1u<<(mNumTracks&7)))
throw std::runtime_error{"Invalid channel enable bits"};

/* Each chunk is exactly one second long, with samples interleaved for each
* enabled track.
* enabled track. The last chunk may be shorter if there isn't enough time
* remaining for a full second.
*/
const auto toread = std::streamsize(mSampleRate * BytesFromQuality(mQuality) * mNumEnabled);
const auto numsamples = std::min(uint64_t{mSampleRate}, mSampleCount-mCurrentSample);

const auto toread = std::streamsize(numsamples * BytesFromQuality(mQuality) * mNumEnabled);
mInFile.read(mSampleChunk.data(), toread);
if(mInFile.gcount() != toread)
throw std::runtime_error{"Failed to read sample chunk"};

std::fill(mSampleChunk.begin()+toread, mSampleChunk.end(), char{});

const auto numsamples = std::min(uint64_t{mSampleRate}, mSampleCount-mCurrentSample);
mCurrentSample += numsamples;
return static_cast<uint32_t>(numsamples);
}
Expand Down Expand Up @@ -452,15 +477,19 @@ auto LafStream::prepareTrack(const size_t trackidx, const size_t count) -> al::s
auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
{
auto laf = std::make_unique<LafStream>();
laf->mInFile = std::ifstream{fname, std::ios_base::binary};
laf->mInFile.open(fname, std::ios_base::binary);

auto marker = std::array<char,9>{};
alassert(laf->mInFile.read(marker.data(), marker.size()));
laf->mInFile.read(marker.data(), marker.size());
if(laf->mInFile.gcount() != marker.size())
throw std::runtime_error{"Failed to read file marker"};
if(std::string_view{marker.data(), marker.size()} != "LIMITLESS"sv)
throw std::runtime_error{"Not an LAF file"};

auto header = std::array<char,10>{};
alassert(laf->mInFile.read(header.data(), header.size()));
laf->mInFile.read(header.data(), header.size());
if(laf->mInFile.gcount() != header.size())
throw std::runtime_error{"Failed to read header"};
while(std::string_view{header.data(), 4} != "HEAD"sv)
{
auto headview = std::string_view{header.data(), header.size()};
Expand All @@ -471,7 +500,7 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
* front, fill in the rest of the header, and continue loading.
*/
const auto hiter = std::copy(header.begin()+hpos, header.end(), header.begin());
alassert(laf->mInFile.read(al::to_address(hiter), std::streamsize(hpos)));
MyAssert(laf->mInFile.read(al::to_address(hiter), std::streamsize(hpos)));
break;
}
if(al::ends_with(headview, "HEA"sv))
Expand All @@ -480,22 +509,22 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
* front, refill the header, and check again.
*/
const auto hiter = std::copy_n(header.end()-3, 3, header.begin());
alassert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-3)));
MyAssert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-3)));
}
else if(al::ends_with(headview, "HE"sv))
{
const auto hiter = std::copy_n(header.end()-2, 2, header.begin());
alassert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-2)));
MyAssert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-2)));
}
else if(headview.back() == 'H')
{
const auto hiter = std::copy_n(header.end()-1, 1, header.begin());
alassert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-1)));
MyAssert(laf->mInFile.read(al::to_address(hiter), std::streamsize(header.size()-1)));
}
else
{
/* The HEAD marker wasn't there. Load some more and check again. */
alassert(laf->mInFile.read(header.data(), header.size()));
MyAssert(laf->mInFile.read(header.data(), header.size()));
}
}

Expand Down Expand Up @@ -529,9 +558,28 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
throw std::runtime_error{"Too many tracks: "+std::to_string(laf->mNumTracks)};

auto chandata = std::vector<char>(laf->mNumTracks*9_uz);
assert(laf->mInFile.read(chandata.data(), std::streamsize(chandata.size())));
laf->mInFile.read(chandata.data(), std::streamsize(chandata.size()));
if(laf->mInFile.gcount() != std::streamsize(chandata.size()))
throw std::runtime_error{"Failed to read channel header data"};

if(laf->mMode == Mode::Channels)
laf->mChannels.reserve(laf->mNumTracks);
else
{
if(laf->mNumTracks < 2)
throw std::runtime_error{"Not enough tracks"};

auto numchans = uint32_t{laf->mNumTracks - 1};
auto numpostracks = uint32_t{1};
while(numpostracks*16 < numchans)
{
--numchans;
++numpostracks;
}
laf->mChannels.reserve(numchans);
laf->mPosTracks.reserve(numpostracks);
}

laf->mChannels.reserve(laf->mNumTracks);
for(uint32_t i{0};i < laf->mNumTracks;++i)
{
static constexpr auto read_float = [](al::span<char,4> input)
Expand All @@ -550,14 +598,14 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>

if(x_axis != x_axis && y_axis == 0.0)
{
alassert(laf->mMode == Mode::Objects);
alassert(i != 0);
MyAssert(laf->mMode == Mode::Objects);
MyAssert(i != 0);
laf->mPosTracks.emplace_back();
}
else
{
alassert(laf->mPosTracks.empty());
alassert(std::isfinite(x_axis) && std::isfinite(y_axis));
MyAssert(laf->mPosTracks.empty());
MyAssert(std::isfinite(x_axis) && std::isfinite(y_axis));
auto &channel = laf->mChannels.emplace_back();
channel.mAzimuth = y_axis;
channel.mElevation = x_axis;
Expand All @@ -570,10 +618,12 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
* handle the audio channels.
*/
if(laf->mMode == Mode::Objects)
alassert(((laf->mChannels.size()-1)>>4) == laf->mPosTracks.size()-1);
MyAssert(((laf->mChannels.size()-1)>>4) == laf->mPosTracks.size()-1);

auto footer = std::array<char,12>{};
alassert(laf->mInFile.read(footer.data(), footer.size()));
laf->mInFile.read(footer.data(), footer.size());
if(laf->mInFile.gcount() != footer.size())
throw std::runtime_error{"Failed to read sample header data"};

laf->mSampleRate = [input=al::span{footer}.first<4>()] {
return uint32_t{uint8_t(input[0]) | (uint32_t{uint8_t(input[1])}<<8)
Expand All @@ -596,7 +646,7 @@ auto LoadLAF(const fs::path &fname) -> std::unique_ptr<LafStream>
* full set of positions. Extra logic will be needed to manage the position
* frame offset separate from each chunk.
*/
alassert(laf->mMode == Mode::Channels || (laf->mSampleRate%FramesPerPos) == 0);
MyAssert(laf->mMode == Mode::Channels || (laf->mSampleRate%FramesPerPos) == 0);

for(size_t i{0};i < laf->mPosTracks.size();++i)
laf->mPosTracks[i].resize(laf->mSampleRate*2_uz, 0.0f);
Expand Down Expand Up @@ -855,7 +905,7 @@ auto main(al::span<std::string_view> args) -> int

int main(int argc, char **argv)
{
alassert(argc >= 0);
MyAssert(argc >= 0);
auto args = std::vector<std::string_view>(static_cast<unsigned int>(argc));
std::copy_n(argv, args.size(), args.begin());
return main(al::span{args});
Expand Down
2 changes: 1 addition & 1 deletion utils/makemhr/loaddef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@ auto ProcessSources(TokenReaderT *tr, HrirDataT *hData, const uint outRate) -> i
hrirPoints, 1.0/factor[ti], azd->mDelays[ti]);
if(resampler)
resampler->process(hrirPoints, hrir);
AverageHrirMagnitude(hData->mFftSize, al::span{hrir}.subspan(irPoints), 1.0/factor[ti],
AverageHrirMagnitude(hData->mFftSize, al::span{hrir}.first(irPoints), 1.0/factor[ti],
azd->mIrs[ti]);
factor[ti] += 1.0;
if(!TrIsOperator(tr, "+"))
Expand Down
2 changes: 1 addition & 1 deletion utils/makemhr/makemhr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ auto StoreMhr(const HrirDataT *hData, const std::string_view filename) -> bool
const uint n{hData->mIrPoints};
uint dither_seed{22222};

std::ofstream ostream{std::filesystem::u8path(filename)};
auto ostream = std::ofstream{std::filesystem::u8path(filename), std::ios::binary};
if(!ostream.is_open())
{
fprintf(stderr, "\nError: Could not open MHR file '%.*s'.\n", al::sizei(filename),
Expand Down

0 comments on commit 3e1e002

Please sign in to comment.