diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-06-19 02:58:23 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2016-06-19 03:31:55 +0300 |
commit | 1151d5831f19a9f24dd0c545a4968606712a62d2 (patch) | |
tree | c978c1b9a3fc86fef531dd412fe6b7668b7c0567 /src/atrac3denc_ut.cpp | |
parent | 8d65a0bd0774e03b3d10354e15f2f3361a2ce26a (diff) | |
download | atracdenc-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.cpp | 162 |
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(); } + + |