P20 dcblock#11000
Conversation
Signed-off-by: Piotr Hoppe <piotr.hoppe@intel.com>
Signed-off-by: Piotr Hoppe <piotr.hoppe@intel.com>
Convert the DC blocking filter from the deprecated audio_stream / process_audio_stream interface to the modern sof_source / sof_sink processing API. The module .process callback now acquires the source and sink circular buffers once via source_get_data() / sink_get_buffer() and passes them to the processing functions as struct cir_buf_source / struct cir_buf_sink views, mirroring the volume component. The generic path uses the shared cir_buf_samples_without_wrap_*() and cir_buf_wrap() helpers, while the HiFi3/HiFi4 variants derive the circular buffer bounds from the same views. Channel count is cached in comp_data during prepare(). Signed-off-by: Piotr Hoppe <piotr.hoppe@intel.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds DC-block unit tests and updates the DC-block component to process audio via the SOF source/sink APIs (using circular buffer views) with updated DSP backends.
Changes:
- Add CMocka math-level and end-to-end process tests for dcblock (S16/S24/S32).
- Refactor dcblock processing functions (generic + HiFi3/HiFi4) to operate on circular buffer views and return status codes.
- Update module adapter integration to use
.processwith source/sink APIs; enable dcblock tests in unit-test config/CMake.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| test/cmocka/src/audio/dcblock/dcblock_process.c | New end-to-end processing test driving the module through source/sink APIs and verifying against a float reference. |
| test/cmocka/src/audio/dcblock/dcblock_math_test.c | New math-level bitexact/DC-removal/saturation tests for dcblock processing kernels. |
| test/cmocka/src/audio/dcblock/CMakeLists.txt | Adds dcblock tests and a minimal audio_for_dcblock library for linking. |
| test/cmocka/src/audio/CMakeLists.txt | Conditionally adds the dcblock test subdirectory when CONFIG_COMP_DCBLOCK is enabled. |
| src/audio/dcblock/dcblock_hifi4.c | Updates HiFi4 kernel to use circular buffer views and return int. |
| src/audio/dcblock/dcblock_hifi3.c | Updates HiFi3 kernel to use circular buffer views; manual wrap logic added. |
| src/audio/dcblock/dcblock_generic.c | Refactors generic kernels to use circular buffer views and return int. |
| src/audio/dcblock/dcblock.h | Updates dcblock_func signature and stores channel count in comp_data. |
| src/audio/dcblock/dcblock.c | Switches module processing to source/sink API; acquires/releases circular buffer views; validates channels. |
| src/arch/xtensa/configs/unit_test_defconfig | Enables CONFIG_COMP_DCBLOCK for unit test builds. |
| cd->source_format = source_get_frm_fmt(sources[0]); | ||
|
|
||
| /* get sink data format */ | ||
| cd->sink_format = sink_get_frm_fmt(sinks[0]); | ||
|
|
||
| /* The processing uses a single channel count as the frame stride for | ||
| * both source and sink, so they must match to avoid corrupt output. | ||
| */ | ||
| if (source_get_channels(sources[0]) != sink_get_channels(sinks[0])) { | ||
| comp_err(dev, "mismatch source/sink stream channels"); | ||
| return -EINVAL; | ||
| } |
| func = dcblock_find_func(SOF_IPC_FRAME_S24_4LE); | ||
| assert_non_null(func); | ||
| func(&cd, &csrc, &csnk, TEST_FRAMES); |
| for (i = 0; i < TEST_FRAMES * TEST_CHANNELS; i++) { | ||
| assert_true(dst[i] <= INT32_MAX); | ||
| assert_true(dst[i] >= INT32_MIN); | ||
| } |
| remaining -= n; | ||
| dst += n; | ||
| if (dst >= y_end) | ||
| dst -= y_size; | ||
| src += n; | ||
| if (src >= x_end) | ||
| src -= x_size; |
| ret = ops->set_configuration(mod, 0, MODULE_CFG_FRAGMENT_SINGLE, | ||
| coeff_size, (const uint8_t *)cdata, | ||
| coeff_size, NULL, 0); |
| dev = comp_new((struct sof_ipc_comp *)ipc); | ||
| free(ipc); | ||
| if (!dev) | ||
| return -EINVAL; |
| ret = dcblock_send_config(mod); | ||
| if (ret) | ||
| return ret; |
| ret = module_prepare(mod, sources, 1, sinks, 1); | ||
| if (ret) | ||
| return ret; |
| endif() | ||
| if(CONFIG_COMP_DCBLOCK) | ||
| add_subdirectory(dcblock) | ||
| endif() |
There was a problem hiding this comment.
same question re: cmocka vs. ztest
kv2019i
left a comment
There was a problem hiding this comment.
I'll let @tmleman comment on the cmocka/ztest transition as he has been converting tests away from cmocka (we do have some left). A test is great to have, no matter which the framework. One question inline, but otherwise code looks good.
| comp_dbg(dev, "entry"); | ||
|
|
||
| frames = MIN(frames, sink_frames); | ||
| frames = MIN(frames, dev->frames); |
There was a problem hiding this comment.
Btw why this min to limit to "dev->frames". This is not done in non-p20 implementation. Would be easier to review if the patch would only map from API to another and not do other changes at the same time.
lgirdwood
left a comment
There was a problem hiding this comment.
LGTM, @piotrhoppeintel can you respond and resolve all copilot comments before we merge. Thanks !
Convert the DC blocking filter from the deprecated audio_stream /
process_audio_stream interface to the modern sof_source / sof_sink
processing API.
The module .process callback now acquires the source and sink circular
buffers once via source_get_data() / sink_get_buffer() and passes them
to the processing functions as struct cir_buf_source / struct cir_buf_sink
views, mirroring the volume component. The generic path uses the shared
cir_buf_samples_without_wrap_*() and cir_buf_wrap() helpers, while the
HiFi3/HiFi4 variants derive the circular buffer bounds from the same
views. Channel count is cached in comp_data during prepare().