aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2015-12-08 01:55:41 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2015-12-08 01:55:41 +0300
commit8b704f5ce2d0666b5b6dc3fb6881b1e6b2dff1bd (patch)
tree359d9493c51d28d6ef8de880c6befe324fb9682b
parentac9a328f40be52aec6665d021d1a42a0d5258d7b (diff)
downloadatracdenc-8b704f5ce2d0666b5b6dc3fb6881b1e6b2dff1bd.tar.gz
support of short window for encoding (without transient detection)
-rw-r--r--src/Makefile4
-rw-r--r--src/atrac/atrac1.h10
-rw-r--r--src/atrac/atrac1_bitalloc.cpp18
-rw-r--r--src/atrac/atrac1_bitalloc.h6
-rw-r--r--src/atrac/atrac1_scale.cpp7
-rw-r--r--src/atrac/atrac1_scale.h2
-rw-r--r--src/atrac_encode_settings.h7
-rw-r--r--src/atracdenc.cpp91
-rw-r--r--src/atracdenc.h23
-rw-r--r--src/atracdenc_ut.cpp81
-rw-r--r--src/main.cpp20
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)))