aboutsummaryrefslogtreecommitdiffstats
path: root/src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2024-05-19 09:44:38 +0000
committerDaniil Cherednik <dan.cherednik@gmail.com>2024-06-14 18:58:21 +0200
commitee120708d72db31012a6aa7b2f6b99960ae1f6d7 (patch)
tree3eae72eb8ee2c337500d0ff8252e69ffe86e1f4b /src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp
parentf018c661a7a6093cabc40784ae3b1fefb96c82de (diff)
downloadatracdenc-ee120708d72db31012a6aa7b2f6b99960ae1f6d7.tar.gz
[AT3P] PQF implementation
M=16 perfect reconstruction polyphase quadrature analysis filter bank
Diffstat (limited to 'src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp')
-rw-r--r--src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp217
1 files changed, 216 insertions, 1 deletions
diff --git a/src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp b/src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp
index ababfcd..c7eec07 100644
--- a/src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp
+++ b/src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp
@@ -17,6 +17,8 @@
*/
#include "atrac3plusdsp.h"
+#include "../atrac3plus_pqf.h"
+#include "../atrac3plus_pqf_data.h"
#include <gtest/gtest.h>
@@ -25,6 +27,8 @@
#include <string.h>
#include <math.h>
+#include <cstdlib>
+
#define SAMPLES 8192
static int read_file(FILE* f, float buf[SAMPLES]) {
@@ -36,6 +40,14 @@ static int read_file(FILE* f, float buf[SAMPLES]) {
return 0;
}
+static void create_chirp(int sz, float* buf) {
+ int i = 0;
+ for(i = 0; i < sz; i++) {
+ float t = i;
+ buf[i] = sinf((t + t * t * 0.5 / 2.0) * 2.0 * M_PI/(float)sz);
+ }
+}
+
TEST(ipqf, CheckOnRefData) {
FILE* mr_f = fopen("test_data/ipqftest_pcm_mr.dat", "r");
if (!mr_f) {
@@ -74,7 +86,210 @@ TEST(ipqf, CheckOnRefData) {
const static float err = 1.0 / (float)(1<<26);
for (int i = 0; i < SAMPLES; i++) {
- //fprintf(stdout, "%f %f\n", tmp[i], ref_data[i]);
EXPECT_NEAR(tmp[i], ref_data[i], err);
}
}
+
+TEST(ipqf, CmpEnergy) {
+ double e1 = 0.0;
+ double e2 = 0.0;
+ double e = 0.0;
+ const static double err = 1.0 / (double)(1ull<<32);
+ for (int i = 0; i < ATRAC3P_SUBBANDS; i++) {
+ e1 = 0.0;
+ e2 = 0.0;
+ for (int j = 0; j < ATRAC3P_PQF_FIR_LEN; j++) {
+ e1 += ff_ipqf_coeffs1[j][i] * ff_ipqf_coeffs1[j][i];
+ e2 += ff_ipqf_coeffs2[j][i] * ff_ipqf_coeffs2[j][i];
+ }
+ if (i) {
+ EXPECT_NEAR(e, e1 + e2, err);
+ }
+ e = e1 + e2;
+ }
+}
+
+TEST(pqf, DC_Short) {
+ int i = 0;
+ float x[2048] = {0};
+ float subbands[2048] = {0};
+ for (i = 0; i < 2048; i++)
+ x[i] = 1;
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+
+ float tmp[2048] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+
+ const static float err = 1.0 / (float)(1<<21);
+
+ for (int i = 368; i < 2048; i++) {
+ EXPECT_NEAR(tmp[i], x[i], err);
+ }
+}
+
+TEST(pqf, DC_Long) {
+ int i = 0;
+ float x[4096] = {0};
+ float subbands[4096] = {0};
+ for (i = 0; i < 4096; i++)
+ x[i] = 1;
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+ at3plus_pqf_do_analyse(actx, x + 2048, subbands + 2048);
+
+ float tmp[4096] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+ ff_atrac3p_ipqf(&sctx, &subbands[2048], &tmp[2048]);
+
+ const static float err = 1.0 / (float)(1<<21);
+
+ for (int i = 368; i < 4096; i++) {
+ EXPECT_NEAR(tmp[i], x[i-368], err);
+ }
+}
+
+TEST(pqf, Seq_Short) {
+ int i = 0;
+ float x[2048] = {0};
+ float subbands[2048] = {0};
+
+ for (i = 0; i < 2048; i++)
+ x[i] = i;
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+
+ float tmp[2048] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+
+ const static float err = 2048.0 / (float)(1<<22);
+
+ for (int i = 368; i < 2048; i++) {
+ EXPECT_NEAR(tmp[i], x[i - 368], err);
+ }
+}
+
+TEST(pqf, Seq_Long) {
+ int i = 0;
+ float x[4096] = {0};
+ float subbands[4096] = {0};
+ for (i = 0; i < 4096; i++)
+ x[i] = i;
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+ at3plus_pqf_do_analyse(actx, x + 2048, subbands + 2048);
+
+ float tmp[4096] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+ ff_atrac3p_ipqf(&sctx, &subbands[2048], &tmp[2048]);
+
+ const static float err = 4096.0 / (float)(1<<21);
+ for (int i = 368; i < 4096; i++) {
+ EXPECT_NEAR(tmp[i], x[i-368], err);
+ }
+}
+
+TEST(pqf, Chirp_Short) {
+ int i = 0;
+ float x[2048] = {0};
+ float subbands[2048] = {0};
+
+ create_chirp(2048, x);
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+
+ float tmp[2048] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+
+ const static float err = 1.0 / (float)(1<<22);
+
+ for (int i = 368; i < 2048; i++) {
+ EXPECT_NEAR(tmp[i], x[i - 368], err);
+ }
+}
+
+TEST(pqf, Chirp_Long) {
+ int i = 0;
+ float x[4096] = {0};
+ float subbands[4096] = {0};
+
+ create_chirp(4096, x);
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+ at3plus_pqf_do_analyse(actx, x + 2048, subbands + 2048);
+
+ float tmp[4096] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+ ff_atrac3p_ipqf(&sctx, &subbands[2048], &tmp[2048]);
+
+ const static float err = 4096.0 / (float)(1<<21);
+ for (int i = 368; i < 4096; i++) {
+ EXPECT_NEAR(tmp[i], x[i-368], err);
+ }
+}
+
+TEST(pqf, Noise_Long) {
+ int i = 0;
+ float x[4096] = {0};
+ float subbands[4096] = {0};
+ for (i = 0; i < 4096; i++)
+ x[i] = (float)rand() / (float)RAND_MAX - 0.5;
+
+ at3plus_pqf_a_ctx_t actx = at3plus_pqf_create_a_ctx();
+
+ at3plus_pqf_do_analyse(actx, x, subbands);
+ at3plus_pqf_do_analyse(actx, x + 2048, subbands + 2048);
+
+ float tmp[4096] = {0};
+
+ Atrac3pIPQFChannelCtx sctx;
+ memset(&sctx, 0, sizeof(sctx));
+
+ ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
+ ff_atrac3p_ipqf(&sctx, &subbands[2048], &tmp[2048]);
+
+ const static float err = 1.0 / (float)(1<<21);
+ for (int i = 368; i < 4096; i++) {
+ EXPECT_NEAR(tmp[i], x[i-368], err);
+ }
+}
+
+