mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
tests: adding lfe-filter-test
so far, this test only includes rewind test, it works as below: let lfe-filter process 2 blocks mono lfe channel audio samples, the sample format is PA_SAMPLE_S16LE, save the processed data to the temp buffer, then rewind the lfe-filter back 1 block and 1.5 blocks respectively, reprocess the audio samples from the rewind position, then comparing the output data with previously saved data. Signed-off-by: Hui Wang <hui.wang@canonical.com>
This commit is contained in:
parent
7fb531d936
commit
98e01c8a9c
2 changed files with 201 additions and 1 deletions
|
|
@ -262,7 +262,8 @@ TESTS_default = \
|
|||
cpu-sconv-test \
|
||||
cpu-volume-test \
|
||||
lock-autospawn-test \
|
||||
mult-s16-test
|
||||
mult-s16-test \
|
||||
lfe-filter-test
|
||||
|
||||
TESTS_norun = \
|
||||
ipacl-test \
|
||||
|
|
@ -554,6 +555,11 @@ mult_s16_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la li
|
|||
mult_s16_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
|
||||
mult_s16_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
|
||||
|
||||
lfe_filter_test_SOURCES = tests/lfe-filter-test.c
|
||||
lfe_filter_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
|
||||
lfe_filter_test_CFLAGS = $(AM_CFLAGS) $(LIBCHECK_CFLAGS)
|
||||
lfe_filter_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBCHECK_LIBS)
|
||||
|
||||
rtstutter_SOURCES = tests/rtstutter.c
|
||||
rtstutter_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINOR@.la libpulse.la libpulsecommon-@PA_MAJORMINOR@.la
|
||||
rtstutter_CFLAGS = $(AM_CFLAGS)
|
||||
|
|
|
|||
194
src/tests/lfe-filter-test.c
Normal file
194
src/tests/lfe-filter-test.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/***
|
||||
This file is part of PulseAudio.
|
||||
|
||||
PulseAudio is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
PulseAudio is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <check.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/sample.h>
|
||||
#include <pulsecore/memblock.h>
|
||||
|
||||
#include <pulsecore/filter/lfe-filter.h>
|
||||
|
||||
struct lfe_filter_test {
|
||||
pa_lfe_filter_t *lf;
|
||||
pa_mempool *pool;
|
||||
pa_sample_spec *ss;
|
||||
};
|
||||
|
||||
static uint8_t *ori_sample_ptr;
|
||||
|
||||
#define ONE_BLOCK_SAMPLES 4096
|
||||
#define TOTAL_SAMPLES 8192
|
||||
|
||||
static void save_data_block(struct lfe_filter_test *lft, void *d, pa_memblock *blk) {
|
||||
uint8_t *dst = d, *src;
|
||||
size_t blk_size = pa_frame_size(lft->ss) * ONE_BLOCK_SAMPLES;
|
||||
|
||||
src = pa_memblock_acquire(blk);
|
||||
memcpy(dst, src, blk_size);
|
||||
pa_memblock_release(blk);
|
||||
}
|
||||
|
||||
static pa_memblock* generate_data_block(struct lfe_filter_test *lft, int start) {
|
||||
pa_memblock *r;
|
||||
uint8_t *d, *s = ori_sample_ptr;
|
||||
size_t blk_size = pa_frame_size(lft->ss) * ONE_BLOCK_SAMPLES;
|
||||
|
||||
pa_assert_se(r = pa_memblock_new(lft->pool, blk_size));
|
||||
d = pa_memblock_acquire(r);
|
||||
memcpy(d, s + start, blk_size);
|
||||
pa_memblock_release(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int compare_data_block(struct lfe_filter_test *lft, void *a, void *b) {
|
||||
int ret = 0;
|
||||
uint32_t i;
|
||||
uint32_t fz = pa_frame_size(lft->ss);
|
||||
uint8_t *r = a, *u = b;
|
||||
|
||||
for (i = 0; i < ONE_BLOCK_SAMPLES * fz; i++) {
|
||||
if (*r++ != *u++) {
|
||||
pa_log_error("lfe-filter-test: test failed, the output data in the position 0x%x of a block does not equal!\n", i);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* in this test case, we pass two blocks of sample data to lfe-filter, each
|
||||
block contains 4096 samples, and don't let rewind_samples exceed TOTAL_SAMPLES */
|
||||
static int lfe_filter_rewind_test(struct lfe_filter_test *lft, int rewind_samples)
|
||||
{
|
||||
int ret = -1, pos, i;
|
||||
pa_memchunk mc;
|
||||
uint8_t *outptr;
|
||||
uint32_t fz = pa_frame_size(lft->ss);
|
||||
|
||||
if (rewind_samples > TOTAL_SAMPLES || rewind_samples < TOTAL_SAMPLES - ONE_BLOCK_SAMPLES) {
|
||||
pa_log_error("lfe-filter-test: Please keep %d samples < rewind_samples < %d samples\n", TOTAL_SAMPLES - ONE_BLOCK_SAMPLES, TOTAL_SAMPLES);
|
||||
return ret;
|
||||
}
|
||||
|
||||
outptr = pa_xmalloc(fz * TOTAL_SAMPLES);
|
||||
|
||||
/* let lfe-filter process all samples first, and save the processed data to the temp buffer,
|
||||
then rewind back to some position, reprocess some samples and compare the output data with
|
||||
the processed data saved before. */
|
||||
for (i = 0; i < TOTAL_SAMPLES / ONE_BLOCK_SAMPLES; i++) {
|
||||
mc.memblock = generate_data_block(lft, i * ONE_BLOCK_SAMPLES * fz);
|
||||
mc.length = pa_memblock_get_length(mc.memblock);
|
||||
mc.index = 0;
|
||||
pa_lfe_filter_process(lft->lf, &mc);
|
||||
save_data_block(lft, outptr + i * ONE_BLOCK_SAMPLES * fz, mc.memblock);
|
||||
pa_memblock_unref(mc.memblock);
|
||||
}
|
||||
|
||||
pa_lfe_filter_rewind(lft->lf, rewind_samples * fz);
|
||||
pos = (TOTAL_SAMPLES - rewind_samples) * fz;
|
||||
mc.memblock = generate_data_block(lft, pos);
|
||||
mc.length = pa_memblock_get_length(mc.memblock);
|
||||
mc.index = 0;
|
||||
pa_lfe_filter_process(lft->lf, &mc);
|
||||
ret = compare_data_block(lft, outptr + pos, pa_memblock_acquire(mc.memblock));
|
||||
pa_memblock_release(mc.memblock);
|
||||
pa_memblock_unref(mc.memblock);
|
||||
|
||||
pa_xfree(outptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
START_TEST (lfe_filter_test) {
|
||||
pa_sample_spec a;
|
||||
int ret = -1;
|
||||
unsigned i, crossover_freq = 120;
|
||||
pa_channel_map chmapmono = {1, {PA_CHANNEL_POSITION_LFE}};
|
||||
struct lfe_filter_test lft;
|
||||
short *tmp_ptr;
|
||||
|
||||
pa_log_set_level(PA_LOG_DEBUG);
|
||||
|
||||
a.channels = 1;
|
||||
a.rate = 44100;
|
||||
a.format = PA_SAMPLE_S16LE;
|
||||
|
||||
lft.ss = &a;
|
||||
pa_assert_se(lft.pool = pa_mempool_new(false, 0));
|
||||
|
||||
/* We prepare pseudo-random input audio samples for lfe-filter rewind testing*/
|
||||
ori_sample_ptr = pa_xmalloc(pa_frame_size(lft.ss) * TOTAL_SAMPLES);
|
||||
tmp_ptr = (short *) ori_sample_ptr;
|
||||
for (i = 0; i < pa_frame_size(lft.ss) * TOTAL_SAMPLES / sizeof(short); i++)
|
||||
*tmp_ptr++ = random();
|
||||
|
||||
/* we create a lfe-filter with cutoff frequency 120Hz and max rewind time 10 seconds */
|
||||
pa_assert_se(lft.lf = pa_lfe_filter_new(&a, &chmapmono, crossover_freq, a.rate * 10));
|
||||
/* rewind to a block boundary */
|
||||
ret = lfe_filter_rewind_test(&lft, ONE_BLOCK_SAMPLES);
|
||||
if (ret)
|
||||
pa_log_error("lfe-filer-test: rewind to block boundary test failed!!!");
|
||||
pa_lfe_filter_free(lft.lf);
|
||||
|
||||
/* we create a lfe-filter with cutoff frequency 120Hz and max rewind time 10 seconds */
|
||||
pa_assert_se(lft.lf = pa_lfe_filter_new(&a, &chmapmono, crossover_freq, a.rate * 10));
|
||||
/* rewind to the middle position of a block */
|
||||
ret = lfe_filter_rewind_test(&lft, ONE_BLOCK_SAMPLES + ONE_BLOCK_SAMPLES / 2);
|
||||
if (ret)
|
||||
pa_log_error("lfe-filer-test: rewind to middle of block test failed!!!");
|
||||
|
||||
pa_xfree(ori_sample_ptr);
|
||||
|
||||
pa_lfe_filter_free(lft.lf);
|
||||
|
||||
pa_mempool_free(lft.pool);
|
||||
|
||||
if (!ret)
|
||||
pa_log_debug("lfe-filter-test: tests for both rewind to block boundary and rewind to middle position of a block passed!");
|
||||
|
||||
fail_unless(ret == 0);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int failed = 0;
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
SRunner *sr;
|
||||
|
||||
if (!getenv("MAKE_CHECK"))
|
||||
pa_log_set_level(PA_LOG_DEBUG);
|
||||
|
||||
s = suite_create("lfe-filter");
|
||||
tc = tcase_create("lfe-filter");
|
||||
tcase_add_test(tc, lfe_filter_test);
|
||||
tcase_set_timeout(tc, 10);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
sr = srunner_create(s);
|
||||
srunner_run_all(sr, CK_NORMAL);
|
||||
failed = srunner_ntests_failed(sr);
|
||||
srunner_free(sr);
|
||||
|
||||
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue