diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-10-20 22:31:55 +0200 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2024-10-20 22:31:55 +0200 |
commit | c8a2949960cc4850d1236de775e83944def7998e (patch) | |
tree | cf709843f11dbe922f3c1734b7358e20de49660d | |
parent | a9cefceaf856df82c6867e853a357b0298d566ce (diff) | |
download | libgha-c8a2949960cc4850d1236de775e83944def7998e.tar.gz |
allow to set partial frame size during gha_adjust_infoat3pghadev
-rw-r--r-- | include/libgha.h | 2 | ||||
-rw-r--r-- | src/gha.c | 39 | ||||
-rw-r--r-- | test/dtmf.c | 2 | ||||
-rw-r--r-- | test/ut.c | 56 |
4 files changed, 76 insertions, 23 deletions
diff --git a/include/libgha.h b/include/libgha.h index 04ebc1b..2dbae63 100644 --- a/include/libgha.h +++ b/include/libgha.h @@ -85,7 +85,7 @@ void gha_extract_many_simple(FLOAT* pcm, struct gha_info* info, size_t k, gha_ct * where n is number of samples to anayze, k is number of harmonics to extract * */ -int gha_adjust_info(const FLOAT* pcm, struct gha_info* info, size_t k, gha_ctx_t ctx, resuidal_cb_t cb, void* user_ctx); +int gha_adjust_info(const FLOAT* pcm, struct gha_info* info, size_t k, gha_ctx_t ctx, resuidal_cb_t cb, void* user_ctx, size_t size_limit); const FLOAT* gha_get_analyzed(gha_ctx_t ctx); @@ -214,25 +214,25 @@ static void gha_estimate_magnitude(const FLOAT* pcm, const FLOAT* regen, size_t result->magnitude = t1 / t2; } -int gha_adjust_info_newton_md(const FLOAT* pcm, struct gha_info* info, size_t dim, gha_ctx_t ctx) +int gha_adjust_info_newton_md(const FLOAT* pcm, struct gha_info* info, size_t dim, gha_ctx_t ctx, size_t sz) { size_t loop; size_t i, j, k, n; for (loop = 0; loop < ctx->max_loops; loop++) { - memcpy(ctx->tmp_buf, pcm, ctx->size * sizeof(FLOAT)); + memcpy(ctx->tmp_buf, pcm, sz * sizeof(FLOAT)); // Use VLA for a while - FLOAT BA[dim][ctx->size]; - FLOAT Bw[dim][ctx->size]; - FLOAT Bp[dim][ctx->size]; - FLOAT BAw[dim][ctx->size]; - FLOAT BAp[dim][ctx->size]; - FLOAT Bww[dim][ctx->size]; - FLOAT Bwp[dim][ctx->size]; - FLOAT Bpp[dim][ctx->size]; - - for (n = 0; n < ctx->size; n++) { + FLOAT BA[dim][sz]; + FLOAT Bw[dim][sz]; + FLOAT Bp[dim][sz]; + FLOAT BAw[dim][sz]; + FLOAT BAp[dim][sz]; + FLOAT Bww[dim][sz]; + FLOAT Bwp[dim][sz]; + FLOAT Bpp[dim][sz]; + + for (n = 0; n < sz; n++) { for (k = 0; k < dim; k++) { FLOAT Ak = (info+k)->magnitude; FLOAT wk = (info+k)->frequency; @@ -258,7 +258,7 @@ int gha_adjust_info_newton_md(const FLOAT* pcm, struct gha_info* info, size_t di memset(M, '\0', dim * 3 * (dim * 3 + 1) * sizeof(double)); for (i = 0; i < dim; i++) { for (j = 0; j < dim; j++) { - for (n = 0; n < ctx->size; n++) { + for (n = 0; n < sz; n++) { if (i == j) { M[i + dim * 0][j + dim * 0] += BA[i][n] * BA[i][n]; M[i + dim * 0][j + dim * 1] += ctx->tmp_buf[n] * BAw[i][n] + BA[i][n] * Bw[i][n]; @@ -296,7 +296,7 @@ int gha_adjust_info_newton_md(const FLOAT* pcm, struct gha_info* info, size_t di } for (k = 0; k < dim; k++) { - for (n = 0; n < ctx->size; n++) { + for (n = 0; n < sz; n++) { M[k + dim * 0][dim * 3] += ctx->tmp_buf[n] * BA[k][n]; M[k + dim * 1][dim * 3] += ctx->tmp_buf[n] * Bw[k][n]; M[k + dim * 2][dim * 3] += ctx->tmp_buf[n] * Bp[k][n]; @@ -397,9 +397,16 @@ void gha_extract_many_simple(FLOAT* pcm, struct gha_info* info, size_t k, gha_ct } } -int gha_adjust_info(const FLOAT* pcm, struct gha_info* info, size_t k, gha_ctx_t ctx, resuidal_cb_t cb, void* user_ctx) +int gha_adjust_info(const FLOAT* pcm, struct gha_info* info, size_t k, gha_ctx_t ctx, resuidal_cb_t cb, void* user_ctx, size_t size_limit) { - int rv = gha_adjust_info_newton_md(pcm, info, k, ctx); + size_t actual_size = ctx->size; + int rv; + + if (size_limit && size_limit < ctx->size) { + actual_size = size_limit; + } + + rv = gha_adjust_info_newton_md(pcm, info, k, ctx, actual_size); if (cb && rv != -1) cb(ctx->tmp_buf, ctx->size, user_ctx); diff --git a/test/dtmf.c b/test/dtmf.c index f7dd487..96a1dcf 100644 --- a/test/dtmf.c +++ b/test/dtmf.c @@ -66,7 +66,7 @@ int main(int argc, char** argv) { } FLOAT resuidal_adjusted; - gha_adjust_info(buf2, res, 2, ctx, &calc_resuidal, &resuidal_adjusted); + gha_adjust_info(buf2, res, 2, ctx, &calc_resuidal, &resuidal_adjusted, 0); if (resuidal_adjusted > resuidal_simple) { fprintf(stderr, "gha_adjust_info wrong result: %f %f\n", resuidal_simple, resuidal_adjusted); @@ -71,12 +71,21 @@ FCT_BGN() UT_CHECK_EQ_FLOAT(res.magnitude, 1.0); UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); - gha_adjust_info(buf, &res, 1, ctx, NULL, NULL); + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 0); fprintf(stderr, "Result: freq: %.10f, phase: %f, magn: %f\n", res.frequency, res.phase, res.magnitude); fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); UT_CHECK_EQ_FLOAT(res.magnitude, 1.0); UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); + res.magnitude = 0.95; /* add some error */ + /* asume this routine will be able to fix error using just part of buffer */ + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 32); + fprintf(stderr, "Result: freq: %.10f, phase: %f, magn: %f\n", res.frequency, res.phase, res.magnitude); + fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); + UT_CHECK_EQ_FLOAT(res.magnitude, 1.0); + UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); + + gha_free_ctx(ctx); } FCT_TEST_END(); @@ -97,7 +106,15 @@ FCT_BGN() UT_CHECK_EQ_FLOAT(res.magnitude, 32768.0); UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); - gha_adjust_info(buf, &res, 1, ctx, NULL, NULL); + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 0); + + fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); + UT_CHECK_EQ_FLOAT(res.magnitude, 32768.0); + UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); + + res.magnitude = 32760.0; + + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 32); fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); UT_CHECK_EQ_FLOAT(res.magnitude, 32768.0); @@ -122,7 +139,7 @@ FCT_BGN() gen(11025.0, 32768, buf, 128); - gha_adjust_info(buf, &res, 1, ctx, NULL, NULL); + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 0); fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); UT_CHECK_EQ_FLOAT(res.magnitude, 32768.0); @@ -152,7 +169,7 @@ FCT_BGN() gen(11025.0, 32768, buf, 128); gen(5000.0, 32768, buf, 128); - gha_adjust_info(buf, res, 2, ctx, NULL, NULL); + gha_adjust_info(buf, res, 2, ctx, NULL, NULL, 0); fct_chk_eq_int(0, compare_phase(0, res[0].phase, 0.01)); UT_CHECK_EQ_FLOAT(round(res[0].magnitude), 32768.0); @@ -186,7 +203,7 @@ FCT_BGN() gen(11025.0, 16384, buf, 128); gen(5512.5, 32768, buf, 128); - gha_adjust_info(buf, res, 2, ctx, NULL, NULL); + gha_adjust_info(buf, res, 2, ctx, NULL, NULL, 0); fct_chk_eq_int(0, compare_phase(0, res[0].phase, 0.01)); UT_CHECK_EQ_FLOAT(round(res[0].magnitude), 16384.0); @@ -203,6 +220,35 @@ FCT_BGN() } FCT_TEST_END(); + FCT_TEST_BGN(one_tone_11025_a32768_partial_frame) + { + float buf[128] = {0}; + gha_ctx_t ctx; + struct gha_info res; + ctx = gha_create_ctx(128); + gha_set_max_magnitude(ctx, 32768); + gha_set_max_loops(ctx, 14); + + gen(11025.0, 32768, buf, 128); + + memset(&buf[96], '\0', 32*sizeof(float)); + + gha_analyze_one(buf, &res, ctx); + + fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); + UT_CHECK_EQ_FLOAT(res.magnitude, 24576.0); + UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); + + gha_adjust_info(buf, &res, 1, ctx, NULL, NULL, 64); + + fct_chk_eq_int(0, compare_phase(0, res.phase, 0.01)); + UT_CHECK_EQ_FLOAT(res.magnitude, 32768.0); + UT_CHECK_EQ_FLOAT(res.frequency, 1.5707963705); + + gha_free_ctx(ctx); + } + FCT_TEST_END(); + FCT_SUITE_END(); } FCT_END(); |