aboutsummaryrefslogtreecommitdiffstats
path: root/src/atrac3denc.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2016-04-17 01:54:12 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2016-07-17 20:26:30 +0300
commitc60933cd2be9f74453fd5db54ac090183b7bff83 (patch)
tree24d8a66cfa235d9a6bdbc14a9b844f691dbeec78 /src/atrac3denc.cpp
parent0c39e61dbebf6a90a22d3db980701231afb75f27 (diff)
downloadatracdenc-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.cpp78
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));
}
};
}