diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-04-17 01:54:12 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-07-17 20:26:30 +0300 |
commit | c60933cd2be9f74453fd5db54ac090183b7bff83 (patch) | |
tree | 24d8a66cfa235d9a6bdbc14a9b844f691dbeec78 /src/atrac3denc.cpp | |
parent | 0c39e61dbebf6a90a22d3db980701231afb75f27 (diff) | |
download | atracdenc-c60933cd2be9f74453fd5db54ac090183b7bff83.tar.gz |
atrac3 analyze and synthesis MLT and possibility to apply gain info
Diffstat (limited to 'src/atrac3denc.cpp')
-rw-r--r-- | src/atrac3denc.cpp | 78 |
1 files changed, 69 insertions, 9 deletions
diff --git a/src/atrac3denc.cpp b/src/atrac3denc.cpp index 9b5b9e6..7557d5e 100644 --- a/src/atrac3denc.cpp +++ b/src/atrac3denc.cpp @@ -1,5 +1,6 @@ #include "atrac3denc.h" #include "atrac/atrac3_bitstream.h" +#include "util.h" #include <assert.h> #include <iostream> @@ -9,11 +10,16 @@ namespace NAtracDEnc { using namespace NMDCT; using std::vector; -void TAtrac3MDCT::Mdct(double specs[1024], double* bands[4]) { +void TAtrac3MDCT::Mdct(double specs[1024], double* bands[4], TGainModulatorArray gainModulators) { for (int band = 0; band < 4; ++band) { double* srcBuff = bands[band]; + double* const curSpec = &specs[band*256]; + TGainModulator modFn = gainModulators[band]; vector<double> tmp(512); memcpy(&tmp[0], &srcBuff[256], 256 * sizeof(double)); + if (modFn) { + modFn(tmp.data(), srcBuff); + } for (int i = 0; i < 256; i++) { srcBuff[256+i] = TAtrac3Data::EncodeWindow[i] * srcBuff[i]; srcBuff[i] = TAtrac3Data::EncodeWindow[255-i] * srcBuff[i]; @@ -21,14 +27,36 @@ void TAtrac3MDCT::Mdct(double specs[1024], double* bands[4]) { memcpy(&tmp[256], &srcBuff[0], 256 * sizeof(double)); const vector<double>& sp = Mdct512(&tmp[0]); assert(sp.size() == 256); - memcpy(&specs[band*256], sp.data(), 256*sizeof(double)); + memcpy(curSpec, sp.data(), 256 * sizeof(double)); + if (band & 1) { + SwapArray(curSpec, 256); + } + } +} + +void TAtrac3MDCT::Midct(double specs[1024], double* bands[4], TGainDemodulatorArray gainDemodulators) { + for (int band = 0; band < 4; ++band) { + double* dstBuff = bands[band]; + double* curSpec = &specs[band*256]; + double* prevBuff = dstBuff + 256; + TAtrac3GainProcessor::TGainDemodulator demodFn = gainDemodulators[band]; if (band & 1) { - for (uint32_t j = 0; j < sp.size() / 2; j++) { - double tmp = specs[band*256 +j]; - specs[band*256 + j] = specs[band*256 + sp.size() - 1 -j]; - specs[band*256 + sp.size() - 1 -j] = tmp; + SwapArray(curSpec, 256); + } + vector<double> inv = Midct512(curSpec); + assert(inv.size()/2 == 256); + for (int j = 0; j < 256; ++j) { + inv[j] *= 2 * DecodeWindow[j]; + inv[511 - j] *= 2 * DecodeWindow[j]; + } + if (demodFn) { + demodFn(dstBuff, inv.data(), prevBuff); + } else { + for (uint32_t j = 0; j < 256; ++j) { + dstBuff[j] = inv[j] + prevBuff[j]; } } + memcpy(prevBuff, &inv[256], sizeof(double)*256); } } @@ -40,6 +68,35 @@ TAtrac3Processor::TAtrac3Processor(TAeaPtr&& oma, const TContainerParams& params TAtrac3Processor::~TAtrac3Processor() {} +TAtrac3MDCT::TGainModulatorArray TAtrac3MDCT::MakeGainModulatorArray(const TAtrac3Data::SubbandInfo& si) { + switch (si.GetQmfNum()) { + case 1: + { + return {{ GainProcessor.Modulate(si.GetGainPoints(0)), TAtrac3MDCT::TGainModulator(), + TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator() }}; + } + case 2: + { + return {{ GainProcessor.Modulate(si.GetGainPoints(0)), GainProcessor.Modulate(si.GetGainPoints(1)), + TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator() }}; + } + case 3: + { + return {{ GainProcessor.Modulate(si.GetGainPoints(0)), GainProcessor.Modulate(si.GetGainPoints(1)), + GainProcessor.Modulate(si.GetGainPoints(2)), TAtrac3MDCT::TGainModulator() }}; + } + case 4: + { + return {{ GainProcessor.Modulate(si.GetGainPoints(0)), GainProcessor.Modulate(si.GetGainPoints(1)), + GainProcessor.Modulate(si.GetGainPoints(2)), GainProcessor.Modulate(si.GetGainPoints(3)) }}; + } + default: + assert(false); + return {}; + + } +} + TPCMEngine<double>::TProcessLambda TAtrac3Processor::GetEncodeLambda() { TOma* omaptr = dynamic_cast<TOma*>(Oma.get()); if (!omaptr) { @@ -53,14 +110,17 @@ TPCMEngine<double>::TProcessLambda TAtrac3Processor::GetEncodeLambda() { vector<double> specs(1024); double src[NumSamples]; for (int i = 0; i < NumSamples; ++i) { - src[i] = data[meta.Channels == 1 ? i : (i * 2 + channel)]; //no mono mode in atrac1. //TODO we can double frame after encoding + src[i] = data[meta.Channels == 1 ? i : (i * 2 + channel)]; //no mono mode in atrac3. //TODO we can double frame after encoding } double* p[4] = {&PcmBuffer[channel][0][0], &PcmBuffer[channel][1][0], &PcmBuffer[channel][2][0], &PcmBuffer[channel][3][0]}; SplitFilterBank[channel].Split(&src[0], p); - Mdct(specs.data(), p); + + TAtrac3Data::SubbandInfo siCur; + + Mdct(specs.data(), p, MakeGainModulatorArray(siCur)); const TBlockSize blockSize(false, false, false); - bitStreamWriter->WriteSoundUnit(TAtrac3SubbandInfo(), Scaler.Scale(specs, blockSize)); + bitStreamWriter->WriteSoundUnit(siCur, Scaler.Scale(specs, blockSize)); } }; } |