Use a higher quality all-pass for the UHJ utils

This commit is contained in:
Chris Robinson 2021-07-30 08:08:16 -07:00
parent 29fba79cd5
commit 47c20b283e
2 changed files with 17 additions and 8 deletions

View File

@ -112,7 +112,7 @@ using FloatBufferSpan = al::span<float,BufferLineSize>;
struct UhjDecoder { struct UhjDecoder {
constexpr static size_t sFilterDelay{128}; constexpr static size_t sFilterDelay{1024};
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{}; alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{};
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mD{}; alignas(16) std::array<float,BufferLineSize+sFilterDelay> mD{};
@ -467,12 +467,13 @@ int main(int argc, char **argv)
auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans); auto decmem = al::vector<std::array<float,BufferLineSize>, 16>(outchans);
auto outmem = std::make_unique<byte4[]>(BufferLineSize*outchans); auto outmem = std::make_unique<byte4[]>(BufferLineSize*outchans);
/* The all-pass filter has a lead-in of 127 samples, and a lead-out of /* A number of initial samples need to be skipped to cut the lead-in
* 128 samples. So after reading the last samples from the input, an * from the all-pass filter delay. The same number of samples need to
* additional 255 samples of silence need to be fed through the decoder * be fed through the decoder after reaching the end of the input file
* for it to finish. * to ensure none of the original input is lost.
*/ */
sf_count_t LeadOut{UhjDecoder::sFilterDelay*2 - 1}; size_t LeadIn{UhjDecoder::sFilterDelay};
sf_count_t LeadOut{UhjDecoder::sFilterDelay};
while(LeadOut > 0) while(LeadOut > 0)
{ {
sf_count_t sgot{sf_readf_float(infile.get(), inmem.get(), BufferLineSize)}; sf_count_t sgot{sf_readf_float(infile.get(), inmem.get(), BufferLineSize)};
@ -490,13 +491,21 @@ int main(int argc, char **argv)
decoder->decode(inmem.get(), static_cast<uint>(ininfo.channels), decmem, got); decoder->decode(inmem.get(), static_cast<uint>(ininfo.channels), decmem, got);
else else
decoder->decode2(inmem.get(), decmem, got); decoder->decode2(inmem.get(), decmem, got);
if(LeadIn >= got)
{
LeadIn -= got;
continue;
}
got -= LeadIn;
for(size_t i{0};i < got;++i) for(size_t i{0};i < got;++i)
{ {
/* Attenuate by -3dB for FuMa output levels. */ /* Attenuate by -3dB for FuMa output levels. */
constexpr float sqrt1_2{0.707106781187f}; constexpr float sqrt1_2{0.707106781187f};
for(size_t j{0};j < outchans;++j) for(size_t j{0};j < outchans;++j)
outmem[i*outchans + j] = f32AsLEBytes(decmem[j][i] * sqrt1_2); outmem[i*outchans + j] = f32AsLEBytes(decmem[j][LeadIn+i] * sqrt1_2);
} }
LeadIn = 0;
size_t wrote{fwrite(outmem.get(), sizeof(byte4)*outchans, got, outfile.get())}; size_t wrote{fwrite(outmem.get(), sizeof(byte4)*outchans, got, outfile.get())};
if(wrote < got) if(wrote < got)

View File

@ -62,7 +62,7 @@ using FloatBufferSpan = al::span<float,BufferLineSize>;
struct UhjEncoder { struct UhjEncoder {
constexpr static size_t sFilterDelay{256}; constexpr static size_t sFilterDelay{1024};
/* Delays and processing storage for the unfiltered signal. */ /* Delays and processing storage for the unfiltered signal. */
alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{}; alignas(16) std::array<float,BufferLineSize+sFilterDelay> mS{};