aboutsummaryrefslogtreecommitdiffstats
path: root/src/atrac
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2024-08-19 23:41:16 +0200
committerDaniil Cherednik <dan.cherednik@gmail.com>2024-08-19 23:41:16 +0200
commit88deefbaecdbf6cfd9e74826b3962dc607c44f78 (patch)
tree077e950aa4ba6df65fc0e179e9e469906f2063d9 /src/atrac
parenta62963044e8d9230375c2f8b7022fa017616fe9f (diff)
downloadatracdenc-88deefbaecdbf6cfd9e74826b3962dc607c44f78.tar.gz
Possibility to "look ahead" during encoding
Diffstat (limited to 'src/atrac')
-rw-r--r--src/atrac/at3p/at3p.cpp42
-rw-r--r--src/atrac/at3p/at3p_gha.cpp26
-rw-r--r--src/atrac/at3p/at3p_gha.h4
-rw-r--r--src/atrac/at3p/at3p_gha_ut.cpp7
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 {