diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2017-10-21 00:37:19 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2017-10-21 00:37:19 +0300 |
commit | bcb2238b2d3c75288c9c6e28ea5b54d17b9ce721 (patch) | |
tree | 759943da164a4fe9377dd17c10093c98a829b023 /src | |
parent | 43b3e1ade5ed5df85d9ccf7d07e4cca9906099cc (diff) | |
download | atracdenc-bcb2238b2d3c75288c9c6e28ea5b54d17b9ce721.tar.gz |
Find optimal BFU num during bit allocation.
Diffstat (limited to 'src')
-rw-r--r-- | src/atrac/atrac3.h | 5 | ||||
-rw-r--r-- | src/atrac/atrac3_bitstream.cpp | 35 | ||||
-rw-r--r-- | src/atrac/atrac3_bitstream.h | 4 | ||||
-rw-r--r-- | src/atrac3denc.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 18 |
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;; |