diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-08-17 00:14:52 +0200 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-08-17 00:14:52 +0200 |
commit | b223290c08204ac0d3e4a826cd586de7aec106cc (patch) | |
tree | ef0cb3040ff8b7fd8114e8bd88bfc6ddfa62174c | |
parent | bb0f0779a6f253a8544a73f8471f4ce3988a61c7 (diff) | |
download | atracdenc-b223290c08204ac0d3e4a826cd586de7aec106cc.tar.gz |
[AT3P] Some GHA related improvements:
* subband can share tone infos with other channel if all tones
in this band matched by frequency, channel marked as leader and folower
* add tool to dump test generated signals into OMA container
(example GHA_UT_DUMP_DIR=/tmp/ ./test/at3plus_gha_ut)
* fix code to produce correct bitstream
* add code to apply PQF to the input frame and pass subbands to GHA
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/atrac/at3p/at3p.cpp | 42 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_bitstream.cpp | 56 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha.cpp | 59 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha.h | 4 | ||||
-rw-r--r-- | src/atrac/at3p/at3p_gha_ut.cpp | 159 | ||||
-rw-r--r-- | src/atrac3p.h | 1 |
7 files changed, 248 insertions, 74 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2ac6049..c82b5dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -101,6 +101,7 @@ set(SOURCE_ATRACDENC_IMPL atrac3denc.cpp atrac/atrac3.cpp atrac/atrac3_bitstream.cpp + atrac/atrac3plus_pqf/atrac3plus_pqf.c atrac/at3p/at3p.cpp atrac/at3p/at3p_bitstream.cpp atrac/at3p/at3p_gha.cpp diff --git a/src/atrac/at3p/at3p.cpp b/src/atrac/at3p/at3p.cpp index 327ed9e..5069354 100644 --- a/src/atrac/at3p/at3p.cpp +++ b/src/atrac/at3p/at3p.cpp @@ -18,24 +18,60 @@ #include <atrac3p.h> +#include <atrac/atrac3plus_pqf/atrac3plus_pqf.h> + #include "at3p_bitstream.h" +#include "at3p_gha.h" + +#include <vector> + +using std::vector; namespace NAtracDEnc { class TAt3PEnc::TImpl { public: - TImpl(ICompressedOutput* out) + TImpl(ICompressedOutput* out, int channels) : BitStream(out, 2048) + , ChannelCtx(channels) + , GhaProcessor(MakeGhaProcessor0(ChannelCtx[0].SubbandsBuf, channels == 2 ? ChannelCtx[1].SubbandsBuf : nullptr)) {} + void EncodeFrame(const TFloat* data, int channels); private: + struct TChannelCtx { + TChannelCtx() + : PqfCtx(at3plus_pqf_create_a_ctx()) + {} + + ~TChannelCtx() { + at3plus_pqf_free_a_ctx(PqfCtx); + } + + at3plus_pqf_a_ctx_t PqfCtx; + TFloat SubbandsBuf[TAt3PEnc::NumSamples]; + }; + TAt3PBitStream BitStream; + vector<TChannelCtx> ChannelCtx; + std::unique_ptr<IGhaProcessor> GhaProcessor; }; void TAt3PEnc::TImpl:: EncodeFrame(const TFloat* data, int channels) { - BitStream.WriteFrame(channels, nullptr); + + 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); + } + + auto tonalBlock = GhaProcessor->DoAnalize(); + BitStream.WriteFrame(channels, tonalBlock); } TAt3PEnc::TAt3PEnc(TCompressedOutputPtr&& out, int channels) @@ -45,7 +81,7 @@ TAt3PEnc::TAt3PEnc(TCompressedOutputPtr&& out, int channels) } TPCMEngine<TFloat>::TProcessLambda TAt3PEnc::GetLambda() { - Impl.reset(new TImpl(Out.get())); + Impl.reset(new TImpl(Out.get(), Channels)); return [this](TFloat* data, const TPCMEngine<TFloat>::ProcessMeta&) { Impl->EncodeFrame(data, Channels); diff --git a/src/atrac/at3p/at3p_bitstream.cpp b/src/atrac/at3p/at3p_bitstream.cpp index 96dee74..df960c2 100644 --- a/src/atrac/at3p/at3p_bitstream.cpp +++ b/src/atrac/at3p/at3p_bitstream.cpp @@ -95,6 +95,28 @@ TAt3PBitStream::TAt3PBitStream(ICompressedOutput* container, uint16_t frameSz) NEnv::SetRoundFloat(); } +static void WriteSubbandFlags(NBitStream::TBitStream& bs, const bool* flags, int numFlags) +{ + + int sum = 0; + for (int i = 0; i < numFlags; i++) { + sum += (uint32_t)flags[i]; + } + + if (sum == 0) { + bs.Write(0, 1); + } else if (sum == numFlags) { + bs.Write(1, 1); + bs.Write(0, 1); + } else { + bs.Write(1, 1); + bs.Write(1, 1); + for (int i = 0; i < numFlags; i++) { + bs.Write(flags[i], 1); + } + } +} + static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3PGhaData* tonalBlock) { //GHA amplidude mode 1 @@ -105,8 +127,8 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 bs.Write(tbHuff.Code, tbHuff.Len); if (channels == 2) { - bs.Write(0, 1); - bs.Write(0, 1); + WriteSubbandFlags(bs, tonalBlock->ToneSharing, tonalBlock->NumToneBands); + WriteSubbandFlags(bs, &tonalBlock->SecondIsLeader, 1); bs.Write(0, 1); } @@ -117,7 +139,7 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 } // Envelope data for (int i = 0; i < tonalBlock->NumToneBands; i++) { - if (ch && !tonalBlock->SecondChBands[i]) { + if (ch && tonalBlock->ToneSharing[i]) { continue; } @@ -132,7 +154,7 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 int mode = 0; //TODO: Calc mode bs.Write(mode, ch + 1); for (int i = 0; i < tonalBlock->NumToneBands; i++) { - if (ch && !tonalBlock->SecondChBands[i]) { + if (ch && tonalBlock->ToneSharing[i]) { continue; } bs.Write(tonalBlock->GetNumWaves(ch, i), 4); @@ -145,7 +167,7 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 } for (int i = 0; i < tonalBlock->NumToneBands; i++) { - if (ch && !tonalBlock->SecondChBands[i]) { + if (ch && tonalBlock->ToneSharing[i]) { continue; } @@ -171,7 +193,7 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 bs.Write(mode, ch + 1); for (int i = 0; i < tonalBlock->NumToneBands; i++) { - if (ch && !tonalBlock->SecondChBands[i]) { + if (ch && tonalBlock->ToneSharing[i]) { continue; } @@ -180,13 +202,15 @@ static void WriteTonalBlock(NBitStream::TBitStream& bs, int channels, const TAt3 continue; } - for (size_t j = 0; j < numWaves; j++) - bs.Write(0, 6); + const auto w = tonalBlock->GetWaves(ch, i); + for (size_t j = 0; j < numWaves; j++) { + bs.Write(w.first[j].AmpSf, 6); + } } // Phase for (int i = 0; i < tonalBlock->NumToneBands; i++) { - if (ch && !tonalBlock->SecondChBands[i]) { + if (ch && tonalBlock->ToneSharing[i]) { continue; } @@ -214,10 +238,20 @@ void TAt3PBitStream::WriteFrame(int channels, const TAt3PGhaData* tonalBlock) // 2 - Nobody know bitStream.Write(channels - 1, 2); + int num_quant_units = 14; + bitStream.Write(num_quant_units - 1, 5); + + for (int ch = 0; ch < channels; ch++) { + bitStream.Write(0, 2); // channel wordlen mode + for (int j = 0; j < num_quant_units; j++) { + bitStream.Write(0, 3); // wordlen + } + } + // Skip some bits to produce correct zero bitstream - bitStream.Write(0, 10); + if (channels == 2) { - bitStream.Write(0, 12); + bitStream.Write(0, 7); } else { bitStream.Write(0, 3); } diff --git a/src/atrac/at3p/at3p_gha.cpp b/src/atrac/at3p/at3p_gha.cpp index 79b3c5b..79c2e8a 100644 --- a/src/atrac/at3p/at3p_gha.cpp +++ b/src/atrac/at3p/at3p_gha.cpp @@ -111,7 +111,7 @@ private: return AmpSfTab; } - uint32_t FillFolowerRes(const TGhaInfoMap& fGhaInfos, TGhaInfoMap::const_iterator& it, uint32_t leaderSb); + uint32_t FillFolowerRes(const TGhaInfoMap& lGha, const TGhaInfoMap& fGha, TGhaInfoMap::const_iterator& it, uint32_t leaderSb); uint32_t AmplitudeToSf(float amp); @@ -358,7 +358,8 @@ void TGhaProcessor::FillResultBuf(const vector<TChannelData>& data) { uint32_t usedContiguousSb[2] = {0, 0}; uint32_t numTones[2] = {0, 0}; - //TODO: Calc used SB just during DoRound routine + + // TODO: This can be improved. Bitstream allows to set leader/folower flag for each band. for (size_t ch = 0; ch < data.size(); ch++) { int cur = -1; for (const auto& info : data[ch].GhaInfos) { @@ -374,13 +375,14 @@ void TGhaProcessor::FillResultBuf(const vector<TChannelData>& data) break; } } - //std::cerr << "ch: " << ch << " usedSb: " << usedContiguousSb[ch] << " numTones: " << numTones[ch] << std::endl; } bool leader = usedContiguousSb[1] > usedContiguousSb[0]; + ResultBuf.SecondIsLeader = leader; ResultBuf.NumToneBands = usedContiguousSb[leader]; + TGhaInfoMap::const_iterator leaderStartIt; TGhaInfoMap::const_iterator folowerIt; if (data.size() == 2) { TWavesChannel& fWaves = ResultBuf.Waves[1]; @@ -389,10 +391,7 @@ void TGhaProcessor::FillResultBuf(const vector<TChannelData>& data) // Yes, see bitstream code fWaves.WaveSbInfos.resize(usedContiguousSb[leader]); folowerIt = data[!leader].GhaInfos.begin(); - - for (size_t i = 0; i < usedContiguousSb[leader]; i++) { - ResultBuf.SecondChBands[i] = false; - } + leaderStartIt = data[leader].GhaInfos.begin(); } const auto& ghaInfos = data[leader].GhaInfos; @@ -423,7 +422,8 @@ void TGhaProcessor::FillResultBuf(const vector<TChannelData>& data) // process folower if present if (data.size() == 2) { - nextFolowerSb = FillFolowerRes(data[!leader].GhaInfos, folowerIt, nextSb); + nextFolowerSb = FillFolowerRes(data[leader].GhaInfos, data[!leader].GhaInfos, folowerIt, nextSb); + leaderStartIt = it; } nextSb = sb; @@ -434,36 +434,53 @@ void TGhaProcessor::FillResultBuf(const vector<TChannelData>& data) } if (data.size() == 2 && nextFolowerSb <= usedContiguousSb[leader]) { - FillFolowerRes(data[!leader].GhaInfos, folowerIt, nextSb); + FillFolowerRes(data[leader].GhaInfos, data[!leader].GhaInfos, folowerIt, nextSb); } } -uint32_t TGhaProcessor::FillFolowerRes(const TGhaInfoMap& fGhaInfos, TGhaInfoMap::const_iterator& it, const uint32_t leaderSb) +uint32_t TGhaProcessor::FillFolowerRes(const TGhaInfoMap& lGhaInfos, const TGhaInfoMap& fGhaInfos, TGhaInfoMap::const_iterator& it, const uint32_t curSb) { TWavesChannel& waves = ResultBuf.Waves[1]; - uint32_t fSb; - if (it != fGhaInfos.end()) { - fSb = ((it->first) >> 10); - ResultBuf.SecondChBands[fSb] = true; - waves.WaveSbInfos[fSb].WaveIndex = waves.WaveParams.size(); - } + + uint32_t folowerSbMode = 0; // 0 - no tones, 1 - sharing band, 2 - own tones set + uint32_t nextSb = 0; + uint32_t added = 0; while (it != fGhaInfos.end()) { - fSb = ((it->first) >> 10); - if (fSb > leaderSb) { - return fSb; + uint32_t sb = ((it->first) >> 10); + if (sb > curSb) { + nextSb = sb; + break; } + // search same indedx in the leader and set coresponding bit + folowerSbMode |= uint8_t(lGhaInfos.find(it->first) == lGhaInfos.end()) + 1u; + const auto freqIndex = it->first & 1023; const auto phaseIndex = GhaPhaseToIndex(it->second.phase); const auto ampSf = AmplitudeToSf(it->second.magnitude); - waves.WaveSbInfos[fSb].WaveNums++; waves.WaveParams.push_back(TAt3PGhaData::TWaveParam{freqIndex, ampSf, 1, phaseIndex}); it++; + added++; + } + + switch (folowerSbMode) { + case 0: + ResultBuf.ToneSharing[curSb] = false; + waves.WaveSbInfos[curSb].WaveNums = 0; + break; + case 1: + ResultBuf.ToneSharing[curSb] = true; + waves.WaveParams.resize(waves.WaveParams.size() - added); + break; + default: + ResultBuf.ToneSharing[curSb] = false; + waves.WaveSbInfos[curSb].WaveIndex = waves.WaveParams.size() - added; + waves.WaveSbInfos[curSb].WaveNums = added; } - return 0; + return nextSb; } uint32_t TGhaProcessor::AmplitudeToSf(float amp) diff --git a/src/atrac/at3p/at3p_gha.h b/src/atrac/at3p/at3p_gha.h index 0daded1..35785a6 100644 --- a/src/atrac/at3p/at3p_gha.h +++ b/src/atrac/at3p/at3p_gha.h @@ -44,7 +44,9 @@ struct TAt3PGhaData { std::array<TWavesChannel, 2> Waves; uint8_t NumToneBands; - bool SecondChBands[16]; + + bool ToneSharing[16]; + bool SecondIsLeader; size_t GetNumWaves(size_t ch, size_t sb) const { return Waves[ch].WaveSbInfos.at(sb).WaveNums; diff --git a/src/atrac/at3p/at3p_gha_ut.cpp b/src/atrac/at3p/at3p_gha_ut.cpp index 718bb04..6554a41 100644 --- a/src/atrac/at3p/at3p_gha_ut.cpp +++ b/src/atrac/at3p/at3p_gha_ut.cpp @@ -1,7 +1,10 @@ +#include "at3p_bitstream.h" #include "at3p_gha.h" +#include "oma.h" #include <gtest/gtest.h> #include <cmath> #include <vector> +#include <cstdlib> using std::vector; @@ -48,6 +51,39 @@ static const TAt3PGhaData __attribute__ ((noinline)) GenAndRunGha(vector<TTestPa return *(processor->DoAnalize()); } +static class TDumper { +public: + TDumper() + : PathPrefix(std::getenv("GHA_UT_DUMP_DIR")) + {} + + void Dump(const TAt3PGhaData* gha, size_t channels, size_t len) { + if (!PathPrefix) { + return; + } + + std::string path = PathPrefix; + path += "/"; + path += ::testing::UnitTest::GetInstance()->current_test_info()->name(); + path += ".oma"; + + std::unique_ptr<TOma> out(new TOma(path, + "test", + channels, + 1, OMAC_ID_ATRAC3PLUS, + 2048, + false)); + + TAt3PBitStream bs(out.get(), 2048); + + for (size_t i = 0; i < len; i++) { + bs.WriteFrame(channels, gha + i); + } + } +private: + const char* PathPrefix; +} Dumper; + // Single channel simple cases TEST(AT3PGHA, 689hz0625__full_frame_mono) { @@ -59,6 +95,7 @@ TEST(AT3PGHA, 689hz0625__full_frame_mono) { EXPECT_EQ(res.GetWaves(0, 0).second, 1); EXPECT_EQ(res.GetWaves(0, 0).first->FreqIndex, 512); EXPECT_EQ(res.GetWaves(0, 0).first->AmpSf, 63); + Dumper.Dump(&res, 1, 1); } @@ -81,6 +118,7 @@ TEST(AT3PGHA, 689hz0625_900hz__full_frame_mono) { EXPECT_EQ(res.GetWaves(0, 0).second, 2); EXPECT_EQ(res.GetWaves(0, 0).first[0].FreqIndex, 512); EXPECT_EQ(res.GetWaves(0, 0).first[1].FreqIndex, 669); + Dumper.Dump(&res, 1, 1); } TEST(AT3PGHA, 400hz_800hz__full_frame_mono) { @@ -92,10 +130,11 @@ TEST(AT3PGHA, 400hz_800hz__full_frame_mono) { EXPECT_EQ(res.GetWaves(0, 0).second, 2); EXPECT_EQ(res.GetWaves(0, 0).first[0].FreqIndex, 297); EXPECT_EQ(res.GetWaves(0, 0).first[1].FreqIndex, 594); + Dumper.Dump(&res, 1, 1); } TEST(AT3PGHA, 689hz0625_2067hz1875__full_frame_mono) { - auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}, {689.0625f, 16384, 128, 256}}, {}); + auto res = GenAndRunGha({{689.0625f, 16384, 0, 128}, {689.0625f, 16384, 128, 256}}, {}); EXPECT_EQ(res.NumToneBands, 2); EXPECT_EQ(res.Waves[0].WaveParams.size(), 2); EXPECT_EQ(res.Waves[0].WaveSbInfos.size(), 2); @@ -103,8 +142,11 @@ TEST(AT3PGHA, 689hz0625_2067hz1875__full_frame_mono) { EXPECT_EQ(res.GetNumWaves(0, 1), 1); EXPECT_EQ(res.GetWaves(0, 0).second, 1); EXPECT_EQ(res.GetWaves(0, 0).first[0].FreqIndex, 512); + EXPECT_EQ(res.GetWaves(0, 0).first->AmpSf, 59); EXPECT_EQ(res.GetWaves(0, 1).second, 1); EXPECT_EQ(res.GetWaves(0, 1).first[0].FreqIndex, 512); + EXPECT_EQ(res.GetWaves(0, 1).first->AmpSf, 59); + Dumper.Dump(&res, 1, 1); } TEST(AT3PGHA, 689hz0625_4823hz4375__full_frame_mono) { @@ -115,11 +157,12 @@ TEST(AT3PGHA, 689hz0625_4823hz4375__full_frame_mono) { EXPECT_EQ(res.GetNumWaves(0, 0), 1); EXPECT_EQ(res.GetWaves(0, 0).second, 1); EXPECT_EQ(res.GetWaves(0, 0).first->FreqIndex, 512); + Dumper.Dump(&res, 1, 1); } // Two channels simple cases -TEST(AT3PGHA, 689hz0625__full_frame_stereo) { +TEST(AT3PGHA, 689hz0625__full_frame_stereo_shared) { auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}}, {{689.0625f, 32768, 0, 128}}); EXPECT_EQ(res.NumToneBands, 1); EXPECT_EQ(res.Waves[0].WaveParams.size(), 1); @@ -128,11 +171,29 @@ TEST(AT3PGHA, 689hz0625__full_frame_stereo) { EXPECT_EQ(res.GetWaves(0, 0).second, 1); EXPECT_EQ(res.GetWaves(0, 0).first->FreqIndex, 512); + EXPECT_EQ(res.ToneSharing[0], true); + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); + Dumper.Dump(&res, 2, 1); +} + +TEST(AT3PGHA, 689hz0625__full_frame_stereo_own) { + auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}}, {{1000.0625f, 32768, 0, 128}}); + EXPECT_EQ(res.NumToneBands, 1); + EXPECT_EQ(res.Waves[0].WaveParams.size(), 1); + EXPECT_EQ(res.Waves[0].WaveSbInfos.size(), 1); + EXPECT_EQ(res.GetNumWaves(0, 0), 1); + EXPECT_EQ(res.GetWaves(0, 0).second, 1); + EXPECT_EQ(res.GetWaves(0, 0).first->FreqIndex, 512); + + EXPECT_EQ(res.ToneSharing[0], false); + EXPECT_EQ(res.Waves[1].WaveParams.size(), 1); EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 1); EXPECT_EQ(res.GetNumWaves(1, 0), 1); EXPECT_EQ(res.GetWaves(1, 0).second, 1); - EXPECT_EQ(res.GetWaves(1, 0).first->FreqIndex, 512); + EXPECT_EQ(res.GetWaves(1, 0).first->FreqIndex, 743); + + Dumper.Dump(&res, 2, 1); } TEST(AT3PGHA, 689hz0625__full_frame_stereo_multiple_second) { @@ -144,12 +205,36 @@ TEST(AT3PGHA, 689hz0625__full_frame_stereo_multiple_second) { EXPECT_EQ(res.GetWaves(0, 0).second, 1); EXPECT_EQ(res.GetWaves(0, 0).first->FreqIndex, 512); + EXPECT_EQ(res.ToneSharing[0], false); EXPECT_EQ(res.Waves[1].WaveParams.size(), 2); EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 1); EXPECT_EQ(res.GetNumWaves(1, 0), 2); EXPECT_EQ(res.GetWaves(1, 0).second, 2); EXPECT_EQ(res.GetWaves(1, 0).first[0].FreqIndex, 512); EXPECT_EQ(res.GetWaves(1, 0).first[1].FreqIndex, 669); + Dumper.Dump(&res, 2, 1); +} + +TEST(AT3PGHA, 689hz0625_2067hz1875__full_frame_stereo_first_is_leader) { + auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}, {689.0625f, 16384, 128, 256}}, + {{689.0625f, 32768, 0, 128}}); + EXPECT_EQ(res.NumToneBands, 2); + EXPECT_EQ(res.Waves[0].WaveParams.size(), 2); + EXPECT_EQ(res.Waves[0].WaveSbInfos.size(), 2); + EXPECT_EQ(res.GetNumWaves(0, 0), 1); + EXPECT_EQ(res.GetNumWaves(0, 1), 1); + EXPECT_EQ(res.GetWaves(0, 0).second, 1); + EXPECT_EQ(res.GetWaves(0, 0).first[0].FreqIndex, 512); + EXPECT_EQ(res.GetWaves(0, 1).second, 1); + EXPECT_EQ(res.GetWaves(0, 1).first[0].FreqIndex, 512); + + EXPECT_EQ(res.ToneSharing[0], true); + EXPECT_EQ(res.ToneSharing[1], false); + + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); // sb0 sharing, sb1 zerro + EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 2); + EXPECT_EQ(res.GetNumWaves(1, 1), 0); + Dumper.Dump(&res, 2, 1); } TEST(AT3PGHA, 689hz0625_2067hz1875__full_frame_stereo_second_is_leader) { @@ -165,14 +250,17 @@ TEST(AT3PGHA, 689hz0625_2067hz1875__full_frame_stereo_second_is_leader) { EXPECT_EQ(res.GetWaves(0, 1).second, 1); EXPECT_EQ(res.GetWaves(0, 1).first[0].FreqIndex, 512); - EXPECT_EQ(res.Waves[1].WaveParams.size(), 1); + EXPECT_EQ(res.ToneSharing[0], true); + EXPECT_EQ(res.ToneSharing[1], false); + + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 2); - EXPECT_EQ(res.GetNumWaves(0, 0), 1); - EXPECT_EQ(res.GetWaves(1, 0).second, 1); - EXPECT_EQ(res.GetWaves(1, 0).first[0].FreqIndex, 512); + EXPECT_EQ(res.GetNumWaves(1, 1), 0); + + Dumper.Dump(&res, 2, 1); } -TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_0_2) { +TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_sharing_0_2) { auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}, {689.0625f, 32768, 128, 256}, {689.0625f, 16384, 256, 384}}, {{689.0625f, 32768, 0, 128}, {689.0625f, 16384, 256, 384}}); EXPECT_EQ(res.NumToneBands, 3); @@ -188,20 +276,15 @@ TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_0_2 EXPECT_EQ(res.GetWaves(0, 2).second, 1); EXPECT_EQ(res.GetWaves(0, 2).first[0].FreqIndex, 512); - EXPECT_EQ(res.SecondChBands[0], true); - EXPECT_EQ(res.SecondChBands[1], false); - EXPECT_EQ(res.SecondChBands[2], true); - EXPECT_EQ(res.Waves[1].WaveParams.size(), 2); - EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 3); - EXPECT_EQ(res.GetNumWaves(1, 0), 1); - EXPECT_EQ(res.GetNumWaves(1, 2), 1); - EXPECT_EQ(res.GetWaves(1, 0).second, 1); - EXPECT_EQ(res.GetWaves(1, 0).first[0].FreqIndex, 512); - EXPECT_EQ(res.GetWaves(1, 2).second, 1); - EXPECT_EQ(res.GetWaves(1, 2).first[0].FreqIndex, 512); + EXPECT_EQ(res.ToneSharing[0], true); + EXPECT_EQ(res.ToneSharing[1], false); + EXPECT_EQ(res.ToneSharing[2], true); + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); + EXPECT_EQ(res.GetNumWaves(1, 1), 0); + Dumper.Dump(&res, 2, 1); } -TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_2) { +TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_sharing_2) { auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}, {689.0625f, 32768, 128, 256}, {689.0625f, 16384, 256, 384}}, {{689.0625f, 16384, 256, 384}}); EXPECT_EQ(res.NumToneBands, 3); @@ -217,17 +300,16 @@ TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_2) EXPECT_EQ(res.GetWaves(0, 2).second, 1); EXPECT_EQ(res.GetWaves(0, 2).first[0].FreqIndex, 512); - EXPECT_EQ(res.SecondChBands[0], false); - EXPECT_EQ(res.SecondChBands[1], false); - EXPECT_EQ(res.SecondChBands[2], true); - EXPECT_EQ(res.Waves[1].WaveParams.size(), 1); - EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 3); - EXPECT_EQ(res.GetNumWaves(1, 2), 1); - EXPECT_EQ(res.GetWaves(1, 2).second, 1); - EXPECT_EQ(res.GetWaves(1, 2).first[0].FreqIndex, 512); + EXPECT_EQ(res.ToneSharing[0], false); + EXPECT_EQ(res.ToneSharing[1], false); + EXPECT_EQ(res.ToneSharing[2], true); + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); + EXPECT_EQ(res.GetNumWaves(1, 0), 0); + EXPECT_EQ(res.GetNumWaves(1, 1), 0); + Dumper.Dump(&res, 2, 1); } -TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_1) { +TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_sharing_1) { auto res = GenAndRunGha({{689.0625f, 32768, 0, 128}, {689.0625f, 32768, 128, 256}, {689.0625f, 16384, 256, 384}}, {{689.0625f, 16384, 128, 256}}); EXPECT_EQ(res.NumToneBands, 3); @@ -243,16 +325,16 @@ TEST(AT3PGHA, 689hz0625_2067hz1875_3445hz3125__full_frame_stereo_folower_has_1) EXPECT_EQ(res.GetWaves(0, 2).second, 1); EXPECT_EQ(res.GetWaves(0, 2).first[0].FreqIndex, 512); - EXPECT_EQ(res.SecondChBands[0], false); - EXPECT_EQ(res.SecondChBands[1], true); - EXPECT_EQ(res.SecondChBands[2], false); - EXPECT_EQ(res.Waves[1].WaveParams.size(), 1); - EXPECT_EQ(res.Waves[1].WaveSbInfos.size(), 3); - EXPECT_EQ(res.GetNumWaves(1, 1), 1); - EXPECT_EQ(res.GetWaves(1, 1).second, 1); - EXPECT_EQ(res.GetWaves(1, 1).first[0].FreqIndex, 512); + EXPECT_EQ(res.ToneSharing[0], false); + EXPECT_EQ(res.ToneSharing[1], true); + EXPECT_EQ(res.ToneSharing[2], false); + EXPECT_EQ(res.Waves[1].WaveParams.size(), 0); + EXPECT_EQ(res.GetNumWaves(1, 0), 0); + EXPECT_EQ(res.GetNumWaves(1, 2), 0); + Dumper.Dump(&res, 2, 1); } +/* TEST(AT3PGHA, max_tones_multiple_bands_full_frame_stereo) { auto res = GenAndRunGha({ {60.0f, 8192, 0, 128}, {120.0f, 8192, 0, 128}, {180.0f, 4096, 0, 128}, {240.0f, 2048, 0, 128}, @@ -354,6 +436,7 @@ TEST(AT3PGHA, max_tones_multiple_bands_full_frame_stereo) { EXPECT_EQ(res.GetWaves(1, 6).first[0].FreqIndex, 45); EXPECT_EQ(res.GetWaves(1, 6).first[1].FreqIndex, 89); EXPECT_EQ(res.GetWaves(1, 6).first[2].FreqIndex, 134); + Dumper.Dump(&res, 2, 1); } - +*/ diff --git a/src/atrac3p.h b/src/atrac3p.h index 31371d1..82f8718 100644 --- a/src/atrac3p.h +++ b/src/atrac3p.h @@ -28,6 +28,7 @@ class TAt3PEnc : public IProcessor<TFloat> { public: TAt3PEnc(TCompressedOutputPtr&& out, int channels); TPCMEngine<TFloat>::TProcessLambda GetLambda() override; + static constexpr int NumSamples = 2048; private: TCompressedOutputPtr Out; int Channels; |