aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2024-10-20 22:31:55 +0200
committerDaniil Cherednik <dan.cherednik@gmail.com>2024-10-20 22:31:55 +0200
commitc8a2949960cc4850d1236de775e83944def7998e (patch)
treecf709843f11dbe922f3c1734b7358e20de49660d
parenta9cefceaf856df82c6867e853a357b0298d566ce (diff)
downloadlibgha-c8a2949960cc4850d1236de775e83944def7998e.tar.gz
allow to set partial frame size during gha_adjust_infoat3pghadev
-rw-r--r--include/libgha.h2
-rw-r--r--src/gha.c39
-rw-r--r--test/dtmf.c2
-rw-r--r--test/ut.c56
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);
diff --git a/src/gha.c b/src/gha.c
index 5cc8470..ff84b86 100644
--- a/src/gha.c
+++ b/src/gha.c
@@ -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);
diff --git a/test/ut.c b/test/ut.c
index 9f17a8d..c1a3ad7 100644
--- a/test/ut.c
+++ b/test/ut.c
@@ -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();