diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2015-12-08 01:55:41 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2015-12-08 01:55:41 +0300 |
commit | 8b704f5ce2d0666b5b6dc3fb6881b1e6b2dff1bd (patch) | |
tree | 359d9493c51d28d6ef8de880c6befe324fb9682b /src | |
parent | ac9a328f40be52aec6665d021d1a42a0d5258d7b (diff) | |
download | atracdenc-8b704f5ce2d0666b5b6dc3fb6881b1e6b2dff1bd.tar.gz |
support of short window for encoding (without transient detection)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/atrac/atrac1.h | 10 | ||||
-rw-r--r-- | src/atrac/atrac1_bitalloc.cpp | 18 | ||||
-rw-r--r-- | src/atrac/atrac1_bitalloc.h | 6 | ||||
-rw-r--r-- | src/atrac/atrac1_scale.cpp | 7 | ||||
-rw-r--r-- | src/atrac/atrac1_scale.h | 2 | ||||
-rw-r--r-- | src/atrac_encode_settings.h | 7 | ||||
-rw-r--r-- | src/atracdenc.cpp | 91 | ||||
-rw-r--r-- | src/atracdenc.h | 23 | ||||
-rw-r--r-- | src/atracdenc_ut.cpp | 81 | ||||
-rw-r--r-- | src/main.cpp | 20 |
11 files changed, 193 insertions, 76 deletions
diff --git a/src/Makefile b/src/Makefile index 5a58987..39783a3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,3 +2,7 @@ all: cd ./mdct && make && cd ../ g++ -std=c++11 -O2 -g main.cpp wav.cpp aea.cpp atracdenc.cpp bitstream/bitstream.cpp atrac/atrac1.cpp atrac/atrac1_dequantiser.cpp atrac/atrac1_scale.cpp atrac/atrac1_bitalloc.cpp mdct/mdct_impl.o -o atracdenc + +test: + g++ -std=c++11 atracdenc_ut.cpp atracdenc.cpp aea.cpp bitstream/bitstream.cpp atrac/atrac1.cpp atrac/atrac1_dequantiser.cpp atrac/atrac1_scale.cpp atrac/atrac1_bitalloc.cpp -I ../3rd/gtest-1.7.0/include/ ../3rd/gtest-1.7.0/src/gtest-all.o ../3rd/gtest-1.7.0/src/gtest_main.o mdct/mdct_impl.o -o atracdenc_ut + ./atracdenc_ut diff --git a/src/atrac/atrac1.h b/src/atrac/atrac1.h index 10cfd0a..c4f349f 100644 --- a/src/atrac/atrac1.h +++ b/src/atrac/atrac1.h @@ -58,6 +58,13 @@ class TBlockSize { stream->Read(2); //skip unused 2 bits return tmp; } + static std::array<int,QMF_BANDS> Create(bool lowShort, bool midShort, bool hiShort) { + std::array<int,QMF_BANDS> tmp; + tmp[0] = lowShort ? 2 : 0; + tmp[1] = midShort ? 2 : 0; + tmp[2] = hiShort ? 3 : 0; + return tmp; + } public: TBlockSize(NBitStream::TBitStream* stream) : LogCount(Parse(stream)) @@ -65,6 +72,9 @@ public: TBlockSize() : LogCount({0,0,0}) //windows are long {} + TBlockSize(bool lowShort, bool midShort, bool hiShort) + : LogCount(Create(lowShort, midShort, hiShort)) + {} const std::array<int,QMF_BANDS> LogCount; }; diff --git a/src/atrac/atrac1_bitalloc.cpp b/src/atrac/atrac1_bitalloc.cpp index 2066cbf..971e392 100644 --- a/src/atrac/atrac1_bitalloc.cpp +++ b/src/atrac/atrac1_bitalloc.cpp @@ -144,7 +144,7 @@ uint32_t TAtrac1SimpleBitAlloc::CheckBfuUsage(bool* changed, uint32_t curBfuId, } return curBfuId; } -uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlocks) { +uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlocks, const TBlockSize& blockSize) { uint32_t bfuIdx = BfuIdxConst ? BfuIdxConst - 1 : 7; bool autoBfu = !BfuIdxConst; double spread = AnalizeSpread(scaledBlocks); @@ -155,8 +155,8 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo for (;;) { bitsPerEachBlock.resize(BfuAmountTab[bfuIdx]); const uint32_t bitsAvaliablePerBfus = SoundUnitSize * 8 - BitsPerBfuAmountTabIdx - 32 - 2 - 3 - bitsPerEachBlock.size() * (BitsPerIDWL + BitsPerIDSF); - double maxShift = 9; - double minShift = -2; + double maxShift = 15; + double minShift = -3; double shift = 3.0; const uint32_t maxBits = bitsAvaliablePerBfus; const uint32_t minBits = bitsAvaliablePerBfus - 110; @@ -169,7 +169,7 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo bitsUsed += SpecsPerBlock[i] * tmpAlloc[i]; } - //std::cout << spread << " bitsUsed: " << bitsUsed << " min " << minBits << " max " << maxBits << endl; + //std::cout << spread << " bitsUsed: " << bitsUsed << " min " << minBits << " max " << maxBits << " " << maxShift << " " << minShift << " " << endl; if (bitsUsed < minBits) { if (maxShift - minShift < 0.1) { if (autoBfu) { @@ -203,24 +203,24 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo } } ApplyBoost(&bitsPerEachBlock, curBitsPerBfus, targetBitsPerBfus); - WriteBitStream(bitsPerEachBlock, scaledBlocks, bfuIdx); + WriteBitStream(bitsPerEachBlock, scaledBlocks, bfuIdx, blockSize); return BfuAmountTab[bfuIdx]; } -void TAtrac1BitStreamWriter::WriteBitStream(const vector<uint32_t>& bitsPerEachBlock, const std::vector<TScaledBlock>& scaledBlocks, uint32_t bfuAmountIdx) { +void TAtrac1BitStreamWriter::WriteBitStream(const vector<uint32_t>& bitsPerEachBlock, const std::vector<TScaledBlock>& scaledBlocks, uint32_t bfuAmountIdx, const TBlockSize& blockSize) { NBitStream::TBitStream bitStream; int bitUsed = 0; if (bfuAmountIdx >= (1 << BitsPerBfuAmountTabIdx)) { cerr << "Wrong bfuAmountIdx (" << bfuAmountIdx << "), frame skiped" << endl; return; } - bitStream.Write(0x2, 2); + bitStream.Write(0x2 - blockSize.LogCount[0], 2); bitUsed+=2; - bitStream.Write(0x2, 2); + bitStream.Write(0x2 - blockSize.LogCount[1], 2); bitUsed+=2; - bitStream.Write(0x3, 2); + bitStream.Write(0x3 - blockSize.LogCount[2], 2); bitStream.Write(0, 2); bitUsed+=4; diff --git a/src/atrac/atrac1_bitalloc.h b/src/atrac/atrac1_bitalloc.h index f0b3746..5081a07 100644 --- a/src/atrac/atrac1_bitalloc.h +++ b/src/atrac/atrac1_bitalloc.h @@ -13,7 +13,7 @@ class IAtrac1BitAlloc { public: IAtrac1BitAlloc() {}; virtual ~IAtrac1BitAlloc() {}; - virtual uint32_t Write(const std::vector<TScaledBlock>& scaledBlocks) = 0; + virtual uint32_t Write(const std::vector<TScaledBlock>& scaledBlocks, const TBlockSize& blockSize) = 0; }; class TBitsBooster : public virtual TAtrac1Data { @@ -31,7 +31,7 @@ public: explicit TAtrac1BitStreamWriter(TAea* container) : Container(container) {}; - void WriteBitStream(const std::vector<uint32_t>& bitsPerEachBlock, const std::vector<TScaledBlock>& scaledBlocks, uint32_t bfuAmountIdx); + void WriteBitStream(const std::vector<uint32_t>& bitsPerEachBlock, const std::vector<TScaledBlock>& scaledBlocks, uint32_t bfuAmountIdx, const TBlockSize& blockSize); }; class TAtrac1SimpleBitAlloc : public TAtrac1BitStreamWriter, public TBitsBooster, public virtual IAtrac1BitAlloc { @@ -47,7 +47,7 @@ public: , FastBfuNumSearch(fastBfuNumSearch) {} ~TAtrac1SimpleBitAlloc() {}; - uint32_t Write(const std::vector<TScaledBlock>& scaledBlocks) override; + uint32_t Write(const std::vector<TScaledBlock>& scaledBlocks, const TBlockSize& blockSize) override; }; } diff --git a/src/atrac/atrac1_scale.cpp b/src/atrac/atrac1_scale.cpp index 461da3a..9346a68 100644 --- a/src/atrac/atrac1_scale.cpp +++ b/src/atrac/atrac1_scale.cpp @@ -22,12 +22,13 @@ TScaler::TScaler() { } } -vector<TScaledBlock> TScaler::Scale(const vector<double>& specs) { +vector<TScaledBlock> TScaler::Scale(const vector<double>& specs, const TBlockSize& blockSize) { vector<TScaledBlock> scaledBlocks; for (uint8_t bandNum = 0; bandNum < QMF_BANDS; ++bandNum) { + const bool shortWinMode = !!blockSize.LogCount[bandNum]; for (uint8_t blockNum = BlocksPerBand[bandNum]; blockNum < BlocksPerBand[bandNum + 1]; ++blockNum) { - const uint16_t specNumStart = SpecsStartLong[blockNum]; - const uint16_t specNumEnd = SpecsStartLong[blockNum] + SpecsPerBlock[blockNum]; + const uint16_t specNumStart = shortWinMode ? SpecsStartShort[blockNum] : SpecsStartLong[blockNum]; + const uint16_t specNumEnd = specNumStart + SpecsPerBlock[blockNum]; double maxAbsSpec = 0; for (uint16_t curSpec = specNumStart; curSpec < specNumEnd; ++curSpec) { const double absSpec = abs(specs[curSpec]); diff --git a/src/atrac/atrac1_scale.h b/src/atrac/atrac1_scale.h index 1b41172..7bbfa56 100644 --- a/src/atrac/atrac1_scale.h +++ b/src/atrac/atrac1_scale.h @@ -17,6 +17,6 @@ class TScaler : public TAtrac1Data { static std::map<uint32_t, uint8_t>ScaleIndex; public: TScaler(); - std::vector<TScaledBlock> Scale(const std::vector<double>& specs); + std::vector<TScaledBlock> Scale(const std::vector<double>& specs, const TBlockSize& blockSize); }; } diff --git a/src/atrac_encode_settings.h b/src/atrac_encode_settings.h index 3400e76..f878a5f 100644 --- a/src/atrac_encode_settings.h +++ b/src/atrac_encode_settings.h @@ -13,16 +13,19 @@ private: const uint32_t BfuIdxConst = 0; const bool FastBfuNumSearch = false; EWindowMode WindowMode = EWindowMode::EWM_LONG_ONLY; + const uint32_t WindowMask = 0; public: TAtrac1EncodeSettings(); - TAtrac1EncodeSettings(uint32_t bfuIdxConst, bool fastBfuNumSearch, EWindowMode windowMode) + TAtrac1EncodeSettings(uint32_t bfuIdxConst, bool fastBfuNumSearch, EWindowMode windowMode, uint32_t windowMask) : BfuIdxConst(bfuIdxConst) , FastBfuNumSearch(fastBfuNumSearch) , WindowMode(windowMode) + , WindowMask(windowMask) {} uint32_t GetBfuIdxConst() const { return BfuIdxConst; } bool GetFastBfuNumSearch() const { return FastBfuNumSearch; } - + EWindowMode GetWindowMode() const {return WindowMode; } + uint32_t GetWindowMask() const {return WindowMask; } }; } diff --git a/src/atracdenc.cpp b/src/atracdenc.cpp index 285c4ec..64fd99a 100644 --- a/src/atracdenc.cpp +++ b/src/atracdenc.cpp @@ -15,8 +15,6 @@ using namespace NMDCT; TAtrac1Processor::TAtrac1Processor(TAeaPtr&& aea, bool mono) : MixChannel(mono) , Aea(std::move(aea)) - , Mdct512(2) - , Mdct256(1) { } @@ -52,91 +50,85 @@ vector<double> midct(double* x, int N) { return res; } -void TAtrac1Processor::Mdct(double Specs[512], double* low, double* mid, double* hi) { +void TAtrac1MDCT::Mdct(double Specs[512], double* low, double* mid, double* hi, const TBlockSize& blockSize) { uint32_t pos = 0; for (uint32_t band = 0; band < QMF_BANDS; band++) { + const uint32_t numMdctBlocks = 1 << blockSize.LogCount[band]; double* srcBuf = (band == 0) ? low : (band == 1) ? mid : hi; uint32_t bufSz = (band == 2) ? 256 : 128; - uint32_t winStart = (band == 2) ? 112 : 48; + const uint32_t blockSz = (numMdctBlocks == 1) ? bufSz : 32; + uint32_t winStart = (numMdctBlocks == 1) ? ((band == 2) ? 112 : 48) : 0; + //compensate level for 3rd band in case of short window + const double multiple = (numMdctBlocks != 1 && band == 2) ? 2.0 : 1.0; vector<double> tmp(512); + uint32_t blockPos = 0; - memcpy(&tmp[winStart], &srcBuf[bufSz], 32 * sizeof(double)); - for (int i = 0; i < 32; i++) { - srcBuf[bufSz + i] = TAtrac1Data::SineWindow[i] * srcBuf[bufSz - 32 + i]; - srcBuf[bufSz - 32 + i] = TAtrac1Data::SineWindow[31 - i] * srcBuf[bufSz - 32 + i]; - } - memcpy(&tmp[winStart+32], &srcBuf[0], bufSz * sizeof(double)); - const vector<double>& sp = (band == 2) ? Mdct512(&tmp[0]) : Mdct256(&tmp[0]); - if (band) { - for (uint32_t j = 0; j < sp.size()/2; j++) { - Specs[pos+j] = sp[bufSz - 1 -j]; - Specs[pos + bufSz - 1 -j] = sp[j]; + for (int k = 0; k < numMdctBlocks; ++k) { + memcpy(&tmp[winStart], &srcBuf[bufSz], 32 * sizeof(double)); + for (int i = 0; i < 32; i++) { + srcBuf[bufSz + i] = TAtrac1Data::SineWindow[i] * srcBuf[blockPos + blockSz - 32 + i]; + srcBuf[blockPos + blockSz - 32 + i] = TAtrac1Data::SineWindow[31 - i] * srcBuf[blockPos + blockSz - 32 + i]; } - } else { + memcpy(&tmp[winStart+32], &srcBuf[blockPos], blockSz * sizeof(double)); + const vector<double>& sp = (numMdctBlocks == 1) ? ((band == 2) ? Mdct512(&tmp[0]) : Mdct256(&tmp[0])) : Mdct64(&tmp[0]); for (uint32_t i = 0; i < sp.size(); i++) { - Specs[pos + i] = sp[i]; - } - } - /* - if (band == 2) { - for (int i = 0; i < bufSz * 2; i++) { - cout << "tmp " << i << " " << tmp[i] << endl; + Specs[blockPos + pos + i] = sp[i] * multiple; } - for (int i = 0; i < sp.size(); ++i ) { - cout << "band2 " << i << " " << Specs[pos + i] << " " << endl; + if (band) { + for (uint32_t j = 0; j < sp.size() / 2; j++) { + double tmp = Specs[blockPos + pos +j]; + Specs[blockPos + pos + j] = Specs[blockPos + pos + sp.size() - 1 -j]; + Specs[blockPos + pos + sp.size() - 1 -j] = tmp; + } } + + blockPos += 32; } - */ pos += bufSz; } } -void TAtrac1Processor::IMdct(double Specs[512], const TBlockSize& mode, double* low, double* mid, double* hi) { +void TAtrac1MDCT::IMdct(double Specs[512], const TBlockSize& mode, double* low, double* mid, double* hi) { uint32_t pos = 0; for (uint32_t band = 0; band < QMF_BANDS; band++) { const uint32_t numMdctBlocks = 1 << mode.LogCount[band]; - const uint32_t blockSize = (numMdctBlocks == 1) ? ((band == 2) ? 256 : 128) : 32; - //if (blockSize == 32) { - // cout << "SHORT: " << numMdctBlocks << " band: " << band << endl; - //} + const uint32_t bufSz = (band == 2) ? 256 : 128; + const uint32_t blockSz = (numMdctBlocks == 1) ? bufSz : 32; uint32_t start = 0; double* dstBuf = (band == 0) ? low : (band == 1) ? mid : hi; - - vector<double> invBuf; - invBuf.resize(512); - double* prevBuf = &dstBuf[blockSize*2 - 16]; - static uint32_t fc; + vector<double> invBuf(512); + double* prevBuf = &dstBuf[bufSz * 2 - 16]; for (uint32_t block = 0; block < numMdctBlocks; block++) { - // cout << "fc counter: " << fc++ << endl; if (band) { - for (uint32_t j = 0; j < blockSize/2; j++) { + for (uint32_t j = 0; j < blockSz/2; j++) { double tmp = Specs[pos+j]; - Specs[pos+j] = Specs[pos + blockSize - 1 -j]; - Specs[pos + blockSize - 1 -j] = tmp; + Specs[pos+j] = Specs[pos + blockSz - 1 -j]; + Specs[pos + blockSz - 1 -j] = tmp; } } - vector<double> inv = (blockSize == 32) ? midct(&Specs[pos], blockSize) : (blockSize == 128) ? Midct256(&Specs[pos]) : Midct512(&Specs[pos]); - for (int i = 0; i < (inv.size()/2); i++) { + vector<double> inv = (numMdctBlocks != 1) ? midct(&Specs[pos], blockSz) : (bufSz == 128) ? Midct256(&Specs[pos]) : Midct512(&Specs[pos]); + for (int i = 0; i < (inv.size()/2); i++) { invBuf[start+i] = inv[i + inv.size()/4]; } vector_fmul_window(dstBuf + start, prevBuf, &invBuf[start], &TAtrac1Data::SineWindow[0], 16); prevBuf = &invBuf[start+16]; - start += blockSize; - pos += blockSize; + start += blockSz; + pos += blockSz; } if (numMdctBlocks == 1) memcpy(dstBuf + 32, &invBuf[16], ((band == 2) ? 240 : 112) * sizeof(double)); for (int j = 0; j < 16; j++) { - dstBuf[blockSize*2 - 16 + j] = invBuf[blockSize - 16 + j]; + dstBuf[bufSz*2 - 16 + j] = invBuf[bufSz - 16 + j]; } } } + TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetDecodeLambda() { return [this](vector<double>* data) { double sum[512]; @@ -176,7 +168,7 @@ TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetEncodeLambda(const TAtra bitAlloc.push_back(new TAtrac1SimpleBitAlloc(Aea.get(), settings.GetBfuIdxConst(), settings.GetFastBfuNumSearch())); //bitAlloc.push_back(new TAtrac1PsyBitAlloc(Aea.get())); - return [this, srcChannels, bitAlloc](vector<double>* data) { + return [this, srcChannels, bitAlloc, settings](vector<double>* data) { for (uint32_t channel = 0; channel < srcChannels; channel++) { double src[NumSamples]; double sum[512]; @@ -187,8 +179,11 @@ TPCMEngine<double>::TProcessLambda TAtrac1Processor::GetEncodeLambda(const TAtra } SplitFilterBank[channel].Split(&src[0], &PcmBufLow[channel][0], &PcmBufMid[channel][0], &PcmBufHi[channel][0]); - Mdct(&specs[0], &PcmBufLow[channel][0], &PcmBufMid[channel][0], &PcmBufHi[channel][0]); - bitAlloc[channel]->Write(Scaler.Scale(specs)); + const uint32_t windowMask = (settings.GetWindowMode() == TAtrac1EncodeSettings::EWindowMode::EWM_SHORT_ONLY) ? settings.GetWindowMask() : 0; + const TBlockSize blockSize(windowMask & 0x1, windowMask & 0x2, windowMask & 0x4); //low, mid, hi + + Mdct(&specs[0], &PcmBufLow[channel][0], &PcmBufMid[channel][0], &PcmBufHi[channel][0], blockSize); + bitAlloc[channel]->Write(Scaler.Scale(specs, blockSize), blockSize); } }; } diff --git a/src/atracdenc.h b/src/atracdenc.h index 8170cd1..5abdac9 100644 --- a/src/atracdenc.h +++ b/src/atracdenc.h @@ -14,7 +14,22 @@ enum EMode { E_DECODE = 2 }; -class TAtrac1Processor : public TAtrac1Data { +class TAtrac1MDCT : public virtual TAtrac1Data { + NMDCT::TMDCT<512> Mdct512; + NMDCT::TMDCT<256> Mdct256; + NMDCT::TMDCT<64> Mdct64; + NMDCT::TMIDCT<512> Midct512; + NMDCT::TMIDCT<256> Midct256; +public: + void IMdct(double specs[512], const TBlockSize& mode, double* low, double* mid, double* hi); + void Mdct(double specs[512], double* low, double* mid, double* hi, const TBlockSize& blockSize); + TAtrac1MDCT() + : Mdct512(2) + , Mdct256(1) + {} +}; + +class TAtrac1Processor : public TAtrac1MDCT, public virtual TAtrac1Data { const bool MixChannel; TAeaPtr Aea; @@ -24,13 +39,7 @@ class TAtrac1Processor : public TAtrac1Data { Atrac1SynthesisFilterBank<double> SynthesisFilterBank[2]; Atrac1SplitFilterBank<double> SplitFilterBank[2]; - NMDCT::TMDCT<512> Mdct512; - NMDCT::TMDCT<256> Mdct256; - NMDCT::TMIDCT<512> Midct512; - NMDCT::TMIDCT<256> Midct256; - void IMdct(double specs[512], const TBlockSize& mode, double* low, double* mid, double* hi); - void Mdct(double specs[512], double* low, double* mid, double* hi); NAtrac1::TScaler Scaler; public: diff --git a/src/atracdenc_ut.cpp b/src/atracdenc_ut.cpp new file mode 100644 index 0000000..975adc5 --- /dev/null +++ b/src/atracdenc_ut.cpp @@ -0,0 +1,81 @@ +#include "atracdenc.h" +#include <gtest/gtest.h> + +#include <vector> +using std::vector; +using namespace NAtracDEnc; + +void CheckResult128(const vector<double>& a, const vector<double>& b) { + for (int i = 0; i < 96; ++i ) { + EXPECT_NEAR(a[i], 4 * b[i+32], 0.0000001); + } +} +void CheckResult256(const vector<double>& a, const vector<double>& b) { + for (int i = 0; i < 192; ++i ) { + EXPECT_NEAR(a[i], 2 * b[i+32], 0.0000001); + } +} + + +TEST(TAtrac1MDCT, TAtrac1MDCTLongEncDec) { + TAtrac1MDCT mdct; + vector<double> low(128 * 2); + vector<double> mid(128 * 2); + vector<double> hi(256 * 2); + vector<double> specs(512 * 2); + + vector<double> lowRes(128 * 2); + vector<double> midRes(128 * 2); + vector<double> hiRes(256 * 2); + + for (int i = 0; i < 128; i++) { + low[i] = mid[i] = i; + } + + for (int i = 0; i < 256; i++) { + hi[i] = i; + } + const TBlockSize blockSize; //default - long + + mdct.Mdct(&specs[0], &low[0], &mid[0], &hi[0], blockSize); + + mdct.IMdct(&specs[0], blockSize, &lowRes[0], &midRes[0], &hiRes[0]); + + CheckResult128(low, lowRes); + CheckResult128(mid, midRes); + CheckResult256(hi, hiRes); +} + +TEST(TAtrac1MDCT, TAtrac1MDCTShortEncDec) { + TAtrac1MDCT mdct; + vector<double> low(128 * 2); + vector<double> mid(128 * 2); + vector<double> hi(256 * 2); + vector<double> specs(512 * 2); + + vector<double> lowRes(128 * 2); + vector<double> midRes(128 * 2); + vector<double> hiRes(256 * 2); + + for (int i = 0; i < 128; i++) { + low[i] = mid[i] = i; + } + const vector<double> lowCopy = low; //in case of short wondow AtracMDCT changed input buffer during calculation + const vector<double> midCopy = mid; + + for (int i = 0; i < 256; i++) { + hi[i] = i; + } + const vector<double> hiCopy = hi; + + const TBlockSize blockSize(true, true, true); //short + + mdct.Mdct(&specs[0], &low[0], &mid[0], &hi[0], blockSize); + + mdct.IMdct(&specs[0], blockSize, &lowRes[0], &midRes[0], &hiRes[0]); + + CheckResult128(lowCopy, lowRes); + CheckResult128(midCopy, midRes); + CheckResult256(hiCopy, hiRes); +} + diff --git a/src/main.cpp b/src/main.cpp index 546ee83..4ef6118 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,7 +41,8 @@ static string GetHelp() { "\n -i input file" "\n -o output file" "\nAdvanced options:\n --bfuidxconst\t Set constant amount of used BFU. WARNING: It is not a lowpass filter! Do not use it to cut off hi frequency." - "\n --bfuidxfast\t enable fast search of BFU amount"; + "\n --bfuidxfast\t enable fast search of BFU amount" + "\n --shortonly[=mask] use short window (32 sample) for all blocks. Mask (specifyed without space) is used to set this option only for given band"; } int main(int argc, char* const* argv) { @@ -52,6 +53,7 @@ int main(int argc, char* const* argv) { { "help", no_argument, NULL, 'h' }, { "bfuidxconst", required_argument, NULL, 1}, { "bfuidxfast", no_argument, NULL, 2}, + { "shortonly", optional_argument, NULL, 3}, { "mono", no_argument, NULL, 'm'}, { NULL, 0, NULL, 0} }; @@ -63,6 +65,8 @@ int main(int argc, char* const* argv) { uint32_t bfuIdxConst = 0; //0 - auto, no const bool fastBfuNumSearch = false; bool mono = false; + TAtrac1EncodeSettings::EWindowMode windowMode = TAtrac1EncodeSettings::EWindowMode::EWM_LONG_ONLY; + uint32_t winMask = 7; while ((ch = getopt_long(argc, argv, "edhi:o:m", longopts, NULL)) != -1) { switch (ch) { case 'e': @@ -99,7 +103,16 @@ int main(int argc, char* const* argv) { case 2: fastBfuNumSearch = true; break; - + case 3: + windowMode = TAtrac1EncodeSettings::EWindowMode::EWM_SHORT_ONLY; + if (optarg) { + winMask = stoi(optarg); + } + cout << "Explicit short window mode specified, bands: low - " << + ((winMask & 1) ? "short": "long") << ", mid - " << + ((winMask & 2) ? "short": "long") << ", hi - " << + ((winMask & 4) ? "short": "long") << endl; + break; default: printUsage(myName); } @@ -146,7 +159,8 @@ int main(int argc, char* const* argv) { } TAtrac1Processor atrac1Processor(move(aeaIO), mono); - auto atracLambda = (mode == E_DECODE) ? atrac1Processor.GetDecodeLambda() : atrac1Processor.GetEncodeLambda(TAtrac1EncodeSettings(bfuIdxConst, fastBfuNumSearch, TAtrac1EncodeSettings::EWindowMode::EWM_LONG_ONLY)); + auto atracLambda = (mode == E_DECODE) ? atrac1Processor.GetDecodeLambda() : + atrac1Processor.GetEncodeLambda(TAtrac1EncodeSettings(bfuIdxConst, fastBfuNumSearch, windowMode, winMask)); uint64_t processed = 0; try { while (totalSamples/4 > (processed = pcmEngine->ApplyProcess(512, atracLambda))) |