aboutsummaryrefslogtreecommitdiffstats
path: root/src/atrac3denc_ut.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2016-06-19 02:58:23 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2016-06-19 03:31:55 +0300
commit1151d5831f19a9f24dd0c545a4968606712a62d2 (patch)
treec978c1b9a3fc86fef531dd412fe6b7668b7c0567 /src/atrac3denc_ut.cpp
parent8d65a0bd0774e03b3d10354e15f2f3361a2ce26a (diff)
downloadatracdenc-1151d5831f19a9f24dd0c545a4968606712a62d2.tar.gz
some improvements of ATRAC3 implementation:atrac3
- simple (ATRAC1 like) psychoacoustic added - possibility to encode tonal components - simple tonal component extractor - refactoring
Diffstat (limited to 'src/atrac3denc_ut.cpp')
-rw-r--r--src/atrac3denc_ut.cpp162
1 files changed, 122 insertions, 40 deletions
diff --git a/src/atrac3denc_ut.cpp b/src/atrac3denc_ut.cpp
index f15c799..e0602a2 100644
--- a/src/atrac3denc_ut.cpp
+++ b/src/atrac3denc_ut.cpp
@@ -1,3 +1,5 @@
+#define ATRAC_UT_PUBLIC
+
#include "atrac3denc.h"
#include <gtest/gtest.h>
@@ -5,21 +7,32 @@
#include <cmath>
using std::vector;
using namespace NAtracDEnc;
+using namespace NAtrac3;
-static void GenerateSignal(double* buf, size_t n, double f, double a) {
+static void GenerateSignal(TFloat* buf, size_t n, TFloat f, TFloat a) {
for (size_t i = 0; i < n; ++i) {
buf[i] = a * sin((M_PI/2) * i * f);
}
}
+static void GenerateSignalWithTransient(TFloat* buf, size_t n, TFloat f, TFloat a,
+ size_t transientPos, size_t transientLen, TFloat transientLev) {
+ assert(transientPos + transientLen < n);
+ GenerateSignal(buf, n, f, a);
+ GenerateSignal(buf+transientPos, transientLen, f, transientLev);
+// for (size_t i = transientPos; i < transientPos + transientLen; ++i) {
+// buf[i] += (i & 1) ? transientLev : - transientLev;
+// }
+}
+
class TWindowTest : public TAtrac3Data {
public:
void RunTest() {
for (size_t i = 0; i < 256; i++) {
- const double ha1 = EncodeWindow[i] / 2.0; //compensation
- const double hs1 = DecodeWindow[i];
- const double hs2 = DecodeWindow[255-i];
- const double res = hs1 / (hs1 * hs1 + hs2 * hs2);
+ const TFloat ha1 = EncodeWindow[i] / 2.0; //compensation
+ const TFloat hs1 = DecodeWindow[i];
+ const TFloat hs2 = DecodeWindow[255-i];
+ const TFloat res = hs1 / (hs1 * hs1 + hs2 * hs2);
EXPECT_NEAR(ha1, res, 0.000000001);
}
}
@@ -62,18 +75,18 @@ public:
TEST(TAtrac3MDCT, TAtrac3MDCTZeroOneBlock) {
TAtrac3MDCT mdct;
- TAtrac3MDCTWorkBuff<double> buff;
- size_t workSz = TAtrac3MDCTWorkBuff<double>::BandBuffSz;
+ TAtrac3MDCTWorkBuff<TFloat> buff;
+ size_t workSz = TAtrac3MDCTWorkBuff<TFloat>::BandBuffSz;
- vector<double> specs(1024);
+ vector<TFloat> specs(1024);
- double* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
+ TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
mdct.Mdct(specs.data(), p);
for(auto s: specs)
EXPECT_NEAR(s, 0.0, 0.0000000001);
- double* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
+ TFloat* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
mdct.Midct(specs.data(), p);
for(size_t i = 0; i < workSz; ++i)
@@ -93,25 +106,25 @@ TEST(TAtrac3MDCT, TAtrac3MDCTZeroOneBlock) {
TEST(TAtrac3MDCT, TAtrac3MDCTSignal) {
TAtrac3MDCT mdct;
- TAtrac3MDCTWorkBuff<double> buff;
- size_t workSz = TAtrac3MDCTWorkBuff<double>::BandBuffSz;
+ TAtrac3MDCTWorkBuff<TFloat> buff;
+ size_t workSz = TAtrac3MDCTWorkBuff<TFloat>::BandBuffSz;
const size_t len = 1024;
- vector<double> signal(len);
- vector<double> signalRes(len);
+ vector<TFloat> signal(len);
+ vector<TFloat> signalRes(len);
GenerateSignal(signal.data(), signal.size(), 0.25, 32768);
for (size_t pos = 0; pos < len; pos += workSz) {
- vector<double> specs(1024);
- memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(double));
+ vector<TFloat> specs(1024);
+ memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
- double* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
+ TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
mdct.Mdct(specs.data(), p);
- double* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
+ TFloat* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
mdct.Midct(specs.data(), t);
- memcpy(signalRes.data() + pos, buff.Band0Res, workSz * sizeof(double));
+ memcpy(signalRes.data() + pos, buff.Band0Res, workSz * sizeof(TFloat));
}
for (int i = workSz; i < len; ++i)
@@ -120,19 +133,19 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignal) {
TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
TAtrac3MDCT mdct;
- TAtrac3MDCTWorkBuff<double> buff;
- size_t workSz = TAtrac3MDCTWorkBuff<double>::BandBuffSz;
+ TAtrac3MDCTWorkBuff<TFloat> buff;
+ size_t workSz = TAtrac3MDCTWorkBuff<TFloat>::BandBuffSz;
const size_t len = 4096;
- vector<double> signal(len, 8000);
- vector<double> signalRes(len);
+ vector<TFloat> signal(len, 8000);
+ vector<TFloat> signalRes(len);
GenerateSignal(signal.data() + 1024, signal.size()-1024, 0.25, 32768);
for (size_t pos = 0; pos < len; pos += workSz) {
- vector<double> specs(1024);
- memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(double));
+ vector<TFloat> specs(1024);
+ memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
- double* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
+ TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
if (pos == 256) { //apply gain modulation
TAtrac3Data::SubbandInfo siCur;
@@ -142,8 +155,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator()});
} else if (pos == 1024) {
TAtrac3Data::SubbandInfo siCur;
- siCur.AddSubbandCurve(0, {{3, 2}});
- siCur.AddSubbandCurve(0, {{2, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{3, 2}, {2, 5}};
+ siCur.AddSubbandCurve(0, std::move(curve));
mdct.Mdct(specs.data(), p, { mdct.GainProcessor.Modulate(siCur.GetGainPoints(0)),
TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator()});
@@ -155,8 +168,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator()});
} else if (pos == 2048) {
TAtrac3Data::SubbandInfo siCur;
- siCur.AddSubbandCurve(0, {{4, 2}});
- siCur.AddSubbandCurve(0, {{1, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{4, 2}, {1, 5}};
+ siCur.AddSubbandCurve(0, std::move(curve));
mdct.Mdct(specs.data(), p, { mdct.GainProcessor.Modulate(siCur.GetGainPoints(0)),
TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator()});
@@ -164,7 +177,7 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
mdct.Mdct(specs.data(), p);
}
- double* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
+ TFloat* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
if (pos == 256) { //restore gain modulation
TAtrac3Data::SubbandInfo siCur;
@@ -187,8 +200,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
} else if (pos == 1024) {
TAtrac3Data::SubbandInfo siCur;
TAtrac3Data::SubbandInfo siNext;
- siNext.AddSubbandCurve(0, {{3, 2}});
- siNext.AddSubbandCurve(0, {{2, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{3, 2}, {2, 5}};
+ siNext.AddSubbandCurve(0, std::move(curve));
mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
@@ -198,8 +211,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
TAtrac3Data::SubbandInfo siNext;
TAtrac3Data::SubbandInfo siCur;
siNext.AddSubbandCurve(0, {{1, 0}});
- siCur.AddSubbandCurve(0, {{3, 2}});
- siCur.AddSubbandCurve(0, {{2, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{3, 2}, {2, 5}};
+ siCur.AddSubbandCurve(0, std::move(curve));
mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
@@ -217,8 +230,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
} else if (pos == 2048) {
TAtrac3Data::SubbandInfo siCur;
TAtrac3Data::SubbandInfo siNext;
- siNext.AddSubbandCurve(0, {{4, 2}});
- siNext.AddSubbandCurve(0, {{1, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{4, 2}, {1, 5}};
+ siNext.AddSubbandCurve(0, std::move(curve));
mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
@@ -227,8 +240,8 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
} else if (pos == 2048 + 256) {
TAtrac3Data::SubbandInfo siNext;
TAtrac3Data::SubbandInfo siCur;
- siCur.AddSubbandCurve(0, {{4, 2}});
- siCur.AddSubbandCurve(0, {{1, 5}});
+ std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve = {{4, 2}, {1, 5}};
+ siCur.AddSubbandCurve(0, std::move(curve));
mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
@@ -237,7 +250,7 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
} else {
mdct.Midct(specs.data(), t);
}
- memcpy(signalRes.data() + pos, buff.Band0Res, workSz * sizeof(double));
+ memcpy(signalRes.data() + pos, buff.Band0Res, workSz * sizeof(TFloat));
}
for (int i = workSz; i < len; ++i) {
//std::cout << "res: " << i << " " << signalRes[i] << std::endl;
@@ -245,9 +258,78 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
}
}
+TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensationAndManualTransient) {
+ TAtrac3MDCT mdct;
+ TAtrac3MDCTWorkBuff<TFloat> buff;
+ size_t workSz = TAtrac3MDCTWorkBuff<TFloat>::BandBuffSz;
+
+ const size_t len = 1024;
+ vector<TFloat> signal(len);
+ vector<TFloat> signalRes(len);
+ GenerateSignalWithTransient(signal.data(), signal.size(), 0.03125, 512.0,
+ 640, 64, 32768.0);
+ const std::vector<TAtrac3Data::SubbandInfo::TGainPoint> curve1 = {{6, 13}, {4, 14}};
+
+ for (size_t pos = 0; pos < len; pos += workSz) {
+ vector<TFloat> specs(1024);
+ memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
+
+ TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
+ //for (int i = 0; i < 256; i++) {
+ // std::cout << i + pos << " " << buff.Band0[i] << std::endl;
+ //}
+
+ if (pos == 512) { //apply gain modulation
+ TAtrac3Data::SubbandInfo siCur;
+ siCur.AddSubbandCurve(0, std::vector<TAtrac3Data::SubbandInfo::TGainPoint>(curve1));
+
+ for (int i = 0; i < 256; i++) {
+ std::cout << i << " " << buff.Band0[i] << std::endl;
+ }
+
+ mdct.Mdct(specs.data(), p, { mdct.GainProcessor.Modulate(siCur.GetGainPoints(0)),
+ TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator(), TAtrac3MDCT::TGainModulator()});
+ } else {
+ mdct.Mdct(specs.data(), p);
+ }
+
+ for (int i = 0; i < specs.size(); ++i) {
+ if (i > 240 && i < 256)
+ specs[i] /= 1.9;
+ }
+ TFloat* t[4] = { buff.Band0Res, buff.Band1Res, buff.Band2Res, buff.Band3Res };
+ if (pos == 512) { //restore gain modulation
+ TAtrac3Data::SubbandInfo siCur;
+ TAtrac3Data::SubbandInfo siNext;
+ siNext.AddSubbandCurve(0, std::vector<TAtrac3Data::SubbandInfo::TGainPoint>(curve1));
+ mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator()});
+ } else if (pos == 768) {
+ TAtrac3Data::SubbandInfo siNext;
+ TAtrac3Data::SubbandInfo siCur;
+ siCur.AddSubbandCurve(0, std::vector<TAtrac3Data::SubbandInfo::TGainPoint>(curve1));
+
+ mdct.Midct(specs.data(), t, {mdct.GainProcessor.Demodulate(siCur.GetGainPoints(0), siNext.GetGainPoints(0)),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator(),
+ TAtrac3MDCT::TAtrac3GainProcessor::TGainDemodulator()});
+ } else {
+ mdct.Midct(specs.data(), t);
+ }
+ memcpy(signalRes.data() + pos, buff.Band0Res, workSz * sizeof(TFloat));
+ }
+ for (int i = workSz; i < len; ++i) {
+ //std::cout << "res: " << i << " " << signalRes[i] << std::endl;
+ EXPECT_NEAR(signal[i - workSz], signalRes[i], 10);
+ }
+}
TEST(TAtrac3MDCT, TAtrac3MDCTWindow) {
TWindowTest test;
test.RunTest();
}
+
+