aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2015-11-24 10:02:17 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2015-11-24 10:04:03 +0300
commit52a4c545a407c48e6e5fe4f2aeada5c83cc6a795 (patch)
tree976333255cf134fe0c04363e867ea48ec5082b8d /src
parent1f9fa0fb09afecc160f3022782572db1b0dae0c0 (diff)
downloadatracdenc-52a4c545a407c48e6e5fe4f2aeada5c83cc6a795.tar.gz
BitsBooster added - use unused by psy bits to reduce aliasing
Diffstat (limited to 'src')
-rw-r--r--src/atrac/atrac1_bitalloc.cpp72
-rw-r--r--src/atrac/atrac1_bitalloc.h14
2 files changed, 81 insertions, 5 deletions
diff --git a/src/atrac/atrac1_bitalloc.cpp b/src/atrac/atrac1_bitalloc.cpp
index bbad317..2066cbf 100644
--- a/src/atrac/atrac1_bitalloc.cpp
+++ b/src/atrac/atrac1_bitalloc.cpp
@@ -9,6 +9,7 @@ namespace NAtrac1 {
using std::vector;
using std::cerr;
using std::endl;
+using std::pair;
static const uint32_t FixedBitAllocTableLong[MAX_BFUS] = {
7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 6,
@@ -16,6 +17,12 @@ static const uint32_t FixedBitAllocTableLong[MAX_BFUS] = {
4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 0, 0, 0
};
+static const uint32_t BitBoostMask[MAX_BFUS] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
//returns 1 for tone-like, 0 - noise-like
static double AnalizeSpread(const std::vector<TScaledBlock>& scaledBlocks) {
double s = 0.0;
@@ -37,6 +44,58 @@ static double AnalizeSpread(const std::vector<TScaledBlock>& scaledBlocks) {
return sigma/14.0;
}
+TBitsBooster::TBitsBooster() {
+ for (uint32_t i = 0; i < MAX_BFUS; ++i) {
+ if (BitBoostMask[i] == 0)
+ continue;
+ const uint32_t nBits = SpecsPerBlock[i];
+ BitsBoostMap.insert(pair<uint32_t, uint32_t>(nBits, i));
+ }
+ MaxBitsPerIteration = BitsBoostMap.size() ? (--BitsBoostMap.end())->first : 0;
+ MinKey = BitsBoostMap.begin()->first;
+}
+
+uint32_t TBitsBooster::ApplyBoost(std::vector<uint32_t>* bitsPerEachBlock, uint32_t cur, uint32_t target) {
+ uint32_t surplus = target - cur;
+ uint32_t key = (surplus > MaxBitsPerIteration) ? MaxBitsPerIteration : surplus;
+ std::multimap<uint32_t, uint32_t>::iterator maxIt = BitsBoostMap.upper_bound(key);
+ //the key too low
+ if (maxIt == BitsBoostMap.begin())
+ return surplus;
+ //std::cout << "key: " << key << " min key: " << MinKey << " it pos: " << maxIt->first << endl;
+
+ while (surplus >= MinKey) {
+ bool done = true;
+ for (std::multimap<uint32_t, uint32_t>::iterator it = BitsBoostMap.begin(); it != maxIt; ++it) {
+ const uint32_t curBits = it->first;
+ const uint32_t curPos = it->second;
+
+ //std::cout << "key: " << key << " curBits: " << curBits << endl;
+ assert(key >= curBits);
+ if (curPos >= bitsPerEachBlock->size())
+ break;
+ if ((*bitsPerEachBlock)[curPos] == 16u)
+ continue;
+ const uint32_t nBitsPerSpec = (*bitsPerEachBlock)[curPos] ? 1 : 2;
+ if ((*bitsPerEachBlock)[curPos] == 0u && curBits * 2 > surplus)
+ continue;
+ if (curBits * nBitsPerSpec > surplus)
+ continue;
+ (*bitsPerEachBlock)[curPos] += nBitsPerSpec;
+ surplus -= curBits * nBitsPerSpec;
+
+ //std::cout << "added: " << curPos << " " << nBitsPerSpec << " got: " << (*bitsPerEachBlock)[curPos] << endl;
+ done = false;
+ }
+ if (done)
+ break;
+ }
+
+ //std::cout << "boost: " << surplus << " was " << target - cur << endl;
+ return surplus;
+}
+
+
vector<uint32_t> TAtrac1SimpleBitAlloc::CalcBitsAllocation(const std::vector<TScaledBlock>& scaledBlocks, const uint32_t bfuNum, const double spread, const double shift) {
vector<uint32_t> bitsPerEachBlock(bfuNum);
for (int i = 0; i < bitsPerEachBlock.size(); ++i) {
@@ -76,8 +135,8 @@ uint32_t TAtrac1SimpleBitAlloc::GetMaxUsedBfuId(const vector<uint32_t>& bitsPerE
}
return idx;
}
-uint32_t TAtrac1SimpleBitAlloc::CheckBfuUsage(bool* changed, uint32_t curBfuId, const vector<uint32_t>& bitsPerEachBlock)
-{
+
+uint32_t TAtrac1SimpleBitAlloc::CheckBfuUsage(bool* changed, uint32_t curBfuId, const vector<uint32_t>& bitsPerEachBlock) {
uint32_t usedBfuId = GetMaxUsedBfuId(bitsPerEachBlock);
if (usedBfuId < curBfuId) {
*changed = true;
@@ -91,6 +150,8 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo
double spread = AnalizeSpread(scaledBlocks);
vector<uint32_t> bitsPerEachBlock(BfuAmountTab[bfuIdx]);
+ uint32_t targetBitsPerBfus;
+ uint32_t curBitsPerBfus;
for (;;) {
bitsPerEachBlock.resize(BfuAmountTab[bfuIdx]);
const uint32_t bitsAvaliablePerBfus = SoundUnitSize * 8 - BitsPerBfuAmountTabIdx - 32 - 2 - 3 - bitsPerEachBlock.size() * (BitsPerIDWL + BitsPerIDSF);
@@ -117,6 +178,7 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo
if (!bfuNumChanged) {
bitsPerEachBlock = tmpAlloc;
}
+ curBitsPerBfus = bitsUsed;
break;
}
maxShift = shift;
@@ -131,12 +193,16 @@ uint32_t TAtrac1SimpleBitAlloc::Write(const std::vector<TScaledBlock>& scaledBlo
if (!bfuNumChanged) {
bitsPerEachBlock = tmpAlloc;
}
+ curBitsPerBfus = bitsUsed;
break;
}
}
- if (!bfuNumChanged)
+ if (!bfuNumChanged) {
+ targetBitsPerBfus = bitsAvaliablePerBfus;
break;
+ }
}
+ ApplyBoost(&bitsPerEachBlock, curBitsPerBfus, targetBitsPerBfus);
WriteBitStream(bitsPerEachBlock, scaledBlocks, bfuIdx);
return BfuAmountTab[bfuIdx];
}
diff --git a/src/atrac/atrac1_bitalloc.h b/src/atrac/atrac1_bitalloc.h
index b90fdc3..f0b3746 100644
--- a/src/atrac/atrac1_bitalloc.h
+++ b/src/atrac/atrac1_bitalloc.h
@@ -4,6 +4,7 @@
#include "../aea.h"
#include "../atrac/atrac1.h"
#include <vector>
+#include <map>
#include <cstdint>
namespace NAtrac1 {
@@ -15,7 +16,16 @@ public:
virtual uint32_t Write(const std::vector<TScaledBlock>& scaledBlocks) = 0;
};
-class TAtrac1BitStreamWriter : public TAtrac1Data {
+class TBitsBooster : public virtual TAtrac1Data {
+ std::multimap<uint32_t, uint32_t> BitsBoostMap; //bits needed -> position
+ uint32_t MaxBitsPerIteration;
+ uint32_t MinKey;
+public:
+ TBitsBooster();
+ uint32_t ApplyBoost(std::vector<uint32_t>* bitsPerEachBlock, uint32_t cur, uint32_t target);
+};
+
+class TAtrac1BitStreamWriter : public virtual TAtrac1Data {
TAea* Container;
public:
explicit TAtrac1BitStreamWriter(TAea* container)
@@ -24,7 +34,7 @@ public:
void WriteBitStream(const std::vector<uint32_t>& bitsPerEachBlock, const std::vector<TScaledBlock>& scaledBlocks, uint32_t bfuAmountIdx);
};
-class TAtrac1SimpleBitAlloc : public TAtrac1BitStreamWriter, public IAtrac1BitAlloc {
+class TAtrac1SimpleBitAlloc : public TAtrac1BitStreamWriter, public TBitsBooster, public virtual IAtrac1BitAlloc {
std::vector<uint32_t> CalcBitsAllocation(const std::vector<TScaledBlock>& scaledBlocks, const uint32_t bfuNum, const double spread, const double shift);
const uint32_t BfuIdxConst;
const bool FastBfuNumSearch;