aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2017-10-21 00:37:19 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2017-10-21 00:37:19 +0300
commitbcb2238b2d3c75288c9c6e28ea5b54d17b9ce721 (patch)
tree759943da164a4fe9377dd17c10093c98a829b023 /src
parent43b3e1ade5ed5df85d9ccf7d07e4cca9906099cc (diff)
downloadatracdenc-bcb2238b2d3c75288c9c6e28ea5b54d17b9ce721.tar.gz
Find optimal BFU num during bit allocation.
Diffstat (limited to 'src')
-rw-r--r--src/atrac/atrac3.h5
-rw-r--r--src/atrac/atrac3_bitstream.cpp35
-rw-r--r--src/atrac/atrac3_bitstream.h4
-rw-r--r--src/atrac3denc.cpp2
-rw-r--r--src/main.cpp18
5 files changed, 38 insertions, 26 deletions
diff --git a/src/atrac/atrac3.h b/src/atrac/atrac3.h
index 5dcdb9e..bc90f7e 100644
--- a/src/atrac/atrac3.h
+++ b/src/atrac/atrac3.h
@@ -250,11 +250,13 @@ public:
};
struct TAtrac3EncoderSettings {
- explicit TAtrac3EncoderSettings(uint32_t bitrate, bool noGainControll, bool noTonalComponents, uint8_t sourceChannels)
+ TAtrac3EncoderSettings(uint32_t bitrate, bool noGainControll,
+ bool noTonalComponents, uint8_t sourceChannels, uint32_t bfuIdxConst)
: ConteinerParams(TAtrac3Data::GetContainerParamsForBitrate(bitrate))
, NoGainControll(noGainControll)
, NoTonalComponents(noTonalComponents)
, SourceChannels(sourceChannels)
+ , BfuIdxConst(bfuIdxConst)
{
std::cout << bitrate << " " << ConteinerParams->Bitrate << std::endl;
}
@@ -262,6 +264,7 @@ struct TAtrac3EncoderSettings {
const bool NoGainControll;
const bool NoTonalComponents;
const uint8_t SourceChannels;
+ const uint32_t BfuIdxConst;
};
} // namespace NAtrac3
diff --git a/src/atrac/atrac3_bitstream.cpp b/src/atrac/atrac3_bitstream.cpp
index 7223d41..0b8d2c8 100644
--- a/src/atrac/atrac3_bitstream.cpp
+++ b/src/atrac/atrac3_bitstream.cpp
@@ -127,47 +127,56 @@ std::pair<uint8_t, uint32_t> TAtrac3BitStreamWriter::CalcSpecsBitsConsumption(co
return std::make_pair(mode, bitsUsed + (mode ? clcBits : vlcBits));
}
+//true - should reencode
+//false - not need to
+static inline bool CheckBfus(uint8_t* numBfu, const vector<uint32_t>& precisionPerEachBlocks)
+{
+ uint8_t curLastBfu = *numBfu - 1;
+ assert(curLastBfu < precisionPerEachBlocks.size());
+ if (precisionPerEachBlocks[curLastBfu] == 0) {
+ *numBfu = curLastBfu;
+ return true;
+ }
+ return false;
+}
std::pair<uint8_t, vector<uint32_t>> TAtrac3BitStreamWriter::CreateAllocation(const vector<TScaledBlock>& scaledBlocks,
uint16_t bitsUsed, int mt[MaxSpecs])
{
TFloat spread = AnalizeScaleFactorSpread(scaledBlocks);
- uint8_t numBfu = 32;
+ uint8_t numBfu = BfuIdxConst ? BfuIdxConst : 32;
vector<uint32_t> precisionPerEachBlocks(numBfu);
uint8_t mode;
- for (;;) {
+ bool cont = true;
+ while (cont) {
precisionPerEachBlocks.resize(numBfu);
const uint32_t bitsAvaliablePerBfus = 8 * Params.FrameSz/2 - bitsUsed -
5 - 1;
TFloat maxShift = 15;
TFloat minShift = -3;
- TFloat shift = 3.0;
- const uint32_t maxBits = bitsAvaliablePerBfus;
- const uint32_t minBits = bitsAvaliablePerBfus - 90;
for (;;) {
+ TFloat shift = (maxShift + minShift) / 2;
const vector<uint32_t>& tmpAlloc = CalcBitsAllocation(scaledBlocks, numBfu, spread, shift);
const auto consumption = CalcSpecsBitsConsumption(scaledBlocks, tmpAlloc, mt);
- if (consumption.second < minBits) {
+ if (consumption.second < bitsAvaliablePerBfus) {
if (maxShift - minShift < 0.1) {
precisionPerEachBlocks = tmpAlloc;
mode = consumption.first;
+ cont = !BfuIdxConst && CheckBfus(&numBfu, precisionPerEachBlocks);
break;
}
- maxShift = shift;
- shift -= (shift - minShift) / 2;
- } else if (consumption.second > maxBits) {
- minShift = shift;
- shift += (maxShift - shift) / 2;
+ maxShift = shift - 0.01;
+ } else if (consumption.second > bitsAvaliablePerBfus) {
+ minShift = shift + 0.01;
} else {
precisionPerEachBlocks = tmpAlloc;
mode = consumption.first;
+ cont = !BfuIdxConst && CheckBfus(&numBfu, precisionPerEachBlocks);;
break;
}
}
- break;
-
}
return { mode, precisionPerEachBlocks };
}
diff --git a/src/atrac/atrac3_bitstream.h b/src/atrac/atrac3_bitstream.h
index 9177bb2..186e267 100644
--- a/src/atrac/atrac3_bitstream.h
+++ b/src/atrac/atrac3_bitstream.h
@@ -47,6 +47,7 @@ class TAtrac3BitStreamWriter : public virtual TAtrac3Data {
};
TOma* Container;
const TContainerParams Params;
+ const uint32_t BfuIdxConst;
std::vector<char> OutBuffer;
uint32_t CLCEnc(const uint32_t selector, const int mantissas[MaxSpecsPerBlock],
@@ -74,9 +75,10 @@ class TAtrac3BitStreamWriter : public virtual TAtrac3Data {
uint16_t EncodeTonalComponents(const std::vector<TTonalBlock>& tonalComponents,
NBitStream::TBitStream* bitStream, uint8_t numQmfBand);
public:
- TAtrac3BitStreamWriter(TOma* container, const TContainerParams& params) //no mono mode for atrac3
+ TAtrac3BitStreamWriter(TOma* container, const TContainerParams& params, uint32_t bfuIdxConst) //no mono mode for atrac3
: Container(container)
, Params(params)
+ , BfuIdxConst(bfuIdxConst)
{
}
diff --git a/src/atrac3denc.cpp b/src/atrac3denc.cpp
index 893733a..cf45fab 100644
--- a/src/atrac3denc.cpp
+++ b/src/atrac3denc.cpp
@@ -337,7 +337,7 @@ TPCMEngine<TFloat>::TProcessLambda TAtrac3Processor::GetEncodeLambda()
abort();
}
- TAtrac3BitStreamWriter* bitStreamWriter = new TAtrac3BitStreamWriter(omaptr, *Params.ConteinerParams);
+ TAtrac3BitStreamWriter* bitStreamWriter = new TAtrac3BitStreamWriter(omaptr, *Params.ConteinerParams, Params.BfuIdxConst);
return [this, bitStreamWriter](TFloat* data, const TPCMEngine<TFloat>::ProcessMeta& meta) {
using TSce = TAtrac3BitStreamWriter::TSingleChannelElement;
diff --git a/src/main.cpp b/src/main.cpp
index 20a8963..4a8daef 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -65,7 +65,7 @@ static string GetHelp()
"\n -i input file"
"\n -o output file"
"\n --bitrate (only if supported by codec)"
- "\nAdvanced options:\n --bfuidxconst\t Set constant amount of used BFU (ATRAC1). "
+ "\nAdvanced options:\n --bfuidxconst\t Set constant amount of used BFU (ATRAC1, ATRAC3). "
"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 (ATRAC1)"
"\n --notransient[=mask] disable transient detection and use optional mask to set bands with short MDCT window "
@@ -259,7 +259,7 @@ int main(int argc, char* const* argv)
std::cout << "BITRATE" << bitrate << std::endl;
break;
case O_BFUIDXCONST:
- bfuIdxConst = checkedStoi(optarg, 1, 8, 0);
+ bfuIdxConst = checkedStoi(optarg, 1, 32, 0);
break;
case O_BFUIDXFAST:
fastBfuNumSearch = true;
@@ -300,14 +300,7 @@ int main(int argc, char* const* argv)
cerr << "No out file" << endl;
return 1;
}
- if (bfuIdxConst > 8) {
- cerr << "Wrong bfuidxconst value ("<< bfuIdxConst << "). "
- << "This is advanced options, use --help to get more information"
- << endl;
- return 1;
- }
-
TPcmEnginePtr pcmEngine;
TAtracProcessorPtr atracProcessor;
uint64_t totalSamples = 0;
@@ -318,6 +311,10 @@ int main(int argc, char* const* argv)
switch (mode) {
case E_ENCODE:
{
+ if (bfuIdxConst > 8) {
+ throw std::invalid_argument("ATRAC1 mode, --bfuidxconst is a index of max used BFU. "
+ "Values [1;8] is allowed");
+ }
using NAtrac1::TAtrac1Data;
NAtrac1::TAtrac1EncodeSettings encoderSettings(bfuIdxConst, fastBfuNumSearch, windowMode, winMask);
PrepareAtrac1Encoder(inFile, outFile, noStdOut, std::move(encoderSettings),
@@ -337,7 +334,8 @@ int main(int argc, char* const* argv)
{
using NAtrac3::TAtrac3Data;
wavIO = OpenWavFile(inFile);
- NAtrac3::TAtrac3EncoderSettings encoderSettings(bitrate * 1024, noGainControl, noTonalComponents, wavIO->GetChannelNum());
+ NAtrac3::TAtrac3EncoderSettings encoderSettings(bitrate * 1024, noGainControl,
+ noTonalComponents, wavIO->GetChannelNum(), bfuIdxConst);
PrepareAtrac3Encoder(inFile, outFile, noStdOut, std::move(encoderSettings),
&totalSamples, wavIO, &pcmEngine, &atracProcessor);
pcmFrameSz = TAtrac3Data::NumSamples;;