diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-08-19 23:41:16 +0200 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-08-19 23:41:16 +0200 |
commit | 88deefbaecdbf6cfd9e74826b3962dc607c44f78 (patch) | |
tree | 077e950aa4ba6df65fc0e179e9e469906f2063d9 /src/atrac | |
parent | a62963044e8d9230375c2f8b7022fa017616fe9f (diff) | |
download | atracdenc-88deefbaecdbf6cfd9e74826b3962dc607c44f78.tar.gz |
Possibility to "look ahead" during encoding
Diffstat (limited to 'src/atrac')
-rw-r--r-- | src/atrac/at3p/at3p.cpp | 42 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha.cpp | 26 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha.h | 4 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha_ut.cpp | 7 |
4 files changed, 51 insertions, 28 deletions
diff --git a/src/atrac/at3p/at3p.cpp b/src/atrac/at3p/at3p.cpp index 5069354..62e51ae 100644 --- a/src/atrac/at3p/at3p.cpp +++ b/src/atrac/at3p/at3p.cpp @@ -23,6 +23,7 @@ #include "at3p_bitstream.h" #include "at3p_gha.h" +#include <cassert> #include <vector> using std::vector; @@ -34,10 +35,10 @@ public: TImpl(ICompressedOutput* out, int channels) : BitStream(out, 2048) , ChannelCtx(channels) - , GhaProcessor(MakeGhaProcessor0(ChannelCtx[0].SubbandsBuf, channels == 2 ? ChannelCtx[1].SubbandsBuf : nullptr)) + , GhaProcessor(MakeGhaProcessor0(channels == 2)) {} - void EncodeFrame(const TFloat* data, int channels); + TPCMEngine<float>::EProcessResult EncodeFrame(const TFloat* data, int channels); private: struct TChannelCtx { TChannelCtx() @@ -49,7 +50,11 @@ private: } at3plus_pqf_a_ctx_t PqfCtx; - TFloat SubbandsBuf[TAt3PEnc::NumSamples]; + + TFloat* NextBuf = Buf1; + TFloat* CurBuf = nullptr; + TFloat Buf1[TAt3PEnc::NumSamples]; + TFloat Buf2[TAt3PEnc::NumSamples]; }; TAt3PBitStream BitStream; @@ -57,21 +62,44 @@ private: std::unique_ptr<IGhaProcessor> GhaProcessor; }; -void TAt3PEnc::TImpl:: +TPCMEngine<float>::EProcessResult TAt3PEnc::TImpl:: EncodeFrame(const TFloat* data, int channels) { + int needMore = 0; for (int ch = 0; ch < channels; ch++) { float src[TAt3PEnc::NumSamples]; for (size_t i = 0; i < NumSamples; ++i) { src[i] = data[i * channels + ch]; } - at3plus_pqf_do_analyse(ChannelCtx[ch].PqfCtx, src, ChannelCtx[ch].SubbandsBuf); + at3plus_pqf_do_analyse(ChannelCtx[ch].PqfCtx, src, ChannelCtx[ch].NextBuf); + if (ChannelCtx[ch].CurBuf == nullptr) { + assert(ChannelCtx[ch].NextBuf == ChannelCtx[ch].Buf1); + ChannelCtx[ch].CurBuf = ChannelCtx[ch].Buf2; + std::swap(ChannelCtx[ch].NextBuf, ChannelCtx[ch].CurBuf); + needMore++; + } + } + + if (needMore == channels) { + return TPCMEngine<TFloat>::EProcessResult::LOOK_AHEAD; } - auto tonalBlock = GhaProcessor->DoAnalize(); + assert(needMore == 0); + + const float* b1 = ChannelCtx[0].CurBuf; + const float* b2 = (channels == 2) ? ChannelCtx[1].CurBuf : nullptr; + + auto tonalBlock = GhaProcessor->DoAnalize(b1, b2); + BitStream.WriteFrame(channels, tonalBlock); + + for (int ch = 0; ch < channels; ch++) { + std::swap(ChannelCtx[ch].NextBuf, ChannelCtx[ch].CurBuf); + } + + return TPCMEngine<TFloat>::EProcessResult::PROCESSED; } TAt3PEnc::TAt3PEnc(TCompressedOutputPtr&& out, int channels) @@ -84,7 +112,7 @@ TPCMEngine<TFloat>::TProcessLambda TAt3PEnc::GetLambda() { Impl.reset(new TImpl(Out.get(), Channels)); return [this](TFloat* data, const TPCMEngine<TFloat>::ProcessMeta&) { - Impl->EncodeFrame(data, Channels); + return Impl->EncodeFrame(data, Channels); }; } diff --git a/src/atrac/at3p/at3p_gha.cpp b/src/atrac/at3p/at3p_gha.cpp index ea73dc3..0a45f61 100644 --- a/src/atrac/at3p/at3p_gha.cpp +++ b/src/atrac/at3p/at3p_gha.cpp @@ -79,11 +79,10 @@ class TGhaProcessor : public IGhaProcessor { }; public: - TGhaProcessor(float* b1, float* b2) - : B1(b1) - , B2(b2) - , LibGhaCtx(gha_create_ctx(128)) + TGhaProcessor(bool stereo) + : LibGhaCtx(gha_create_ctx(128)) , AmpSfTab(CreateAmpSfTab()) + , Stereo(stereo) { FillSubbandAth(&SubbandAth[0]); } @@ -93,7 +92,7 @@ public: gha_free_ctx(LibGhaCtx); } - const TAt3PGhaData* DoAnalize() override; + const TAt3PGhaData* DoAnalize(const float* b1, const float* b2) override; private: static void FillSubbandAth(float* out) { const auto ath = CalcATH(16 * 1024, 44100); @@ -125,25 +124,20 @@ private: pair<uint32_t, uint32_t> FindPos(const float* src, const float* analized, float magn, uint32_t freqIdx) const; void FillResultBuf(const vector<TChannelData>& data); - bool IsStereo() const { - return (bool)B2; - } - - float* const B1; - float* const B2; gha_ctx_t LibGhaCtx; const TAmpSfTab AmpSfTab; float SubbandAth[SUBBANDS]; TAt3PGhaData ResultBuf; + const bool Stereo; }; -const TAt3PGhaData* TGhaProcessor::DoAnalize() +const TAt3PGhaData* TGhaProcessor::DoAnalize(const float* b1, const float* b2) { - vector<TChannelData> data((size_t)IsStereo() + 1); + vector<TChannelData> data((size_t)Stereo + 1); bool progress[2] = {false}; for (size_t ch = 0; ch < data.size(); ch++) { - const float* b = (ch == 0) ? B1 : B2; + const float* b = (ch == 0) ? b1 : b2; data[ch].SrcBuf = b; memcpy(&data[ch].Buf[0], b, sizeof(float) * CHANNEL_BUF_SZ); } @@ -494,9 +488,9 @@ uint32_t TGhaProcessor::AmplitudeToSf(float amp) } // namespace -std::unique_ptr<IGhaProcessor> MakeGhaProcessor0(float* b1, float* b2) +std::unique_ptr<IGhaProcessor> MakeGhaProcessor0(bool stereo) { - return std::unique_ptr<TGhaProcessor>(new TGhaProcessor(b1, b2)); + return std::unique_ptr<TGhaProcessor>(new TGhaProcessor(stereo)); } } // namespace NAtracDEnc diff --git a/src/atrac/at3p/at3p_gha.h b/src/atrac/at3p/at3p_gha.h index 35785a6..5fef68d 100644 --- a/src/atrac/at3p/at3p_gha.h +++ b/src/atrac/at3p/at3p_gha.h @@ -61,10 +61,10 @@ struct TAt3PGhaData { class IGhaProcessor { public: virtual ~IGhaProcessor() {} - virtual const TAt3PGhaData* DoAnalize() = 0; + virtual const TAt3PGhaData* DoAnalize(const float* b1, const float* b2) = 0; }; -std::unique_ptr<IGhaProcessor> MakeGhaProcessor0(float* b1, float* b2); +std::unique_ptr<IGhaProcessor> MakeGhaProcessor0(bool stereo); } // namespace NAtracDEnc diff --git a/src/atrac/at3p/at3p_gha_ut.cpp b/src/atrac/at3p/at3p_gha_ut.cpp index 6554a41..a65cb35 100644 --- a/src/atrac/at3p/at3p_gha_ut.cpp +++ b/src/atrac/at3p/at3p_gha_ut.cpp @@ -45,10 +45,11 @@ static const TAt3PGhaData __attribute__ ((noinline)) GenAndRunGha(vector<TTestPa } } - auto processor = MakeGhaProcessor0(buf1.data(), buf2.empty() ? nullptr : buf2.data()); + auto processor = MakeGhaProcessor0(!p2.empty()); + const float* b1 = buf1.data(); + const float* b2 = buf2.empty() ? nullptr : buf2.data(); - - return *(processor->DoAnalize()); + return *(processor->DoAnalize(b1, b2)); } static class TDumper { |