-
Notifications
You must be signed in to change notification settings - Fork 347
Add support for hostless/dailess pipelines #10329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for hostless pipelines using a tone generator as an example. The changes enable pipelines to run without a host connection by introducing direction awareness and implementing the tone generator as a modular component.
Key changes:
- Implemented pipeline direction tracking in IPC4 to support hostless operation
- Refactored tone generator from legacy component to module adapter architecture
- Added configuration support for tone generator in SDW platform topologies
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tools/topology/topology2/platform/intel/sdw-amp-generic.conf | Adds tone generator pipeline configuration with PCM definition and routing |
| tools/topology/topology2/include/pipelines/virtual-siggen-mixin-playback.conf | Defines new virtual signal generator to mixer pipeline for tone playback |
| tools/topology/topology2/include/components/virtual.conf | Adds stream_name attribute to virtual widget component |
| tools/topology/topology2/include/components/siggen.conf | New signal generator component definition with configuration attributes |
| tools/topology/topology2/cavs-sdw.conf | Includes new pipeline and adds SPK_TONE_PLAYBACK configuration flag |
| src/ipc/ipc4/helper.c | Extracts and stores pipeline direction from IPC extension data |
| src/include/sof/audio/pipeline.h | Adds direction tracking fields to pipeline structure |
| src/include/ipc4/pipeline.h | Defines direction bitfields in IPC4 pipeline extension structure |
| src/audio/tone.toml | Adds module configuration manifest for tone generator |
| src/audio/tone.c | Refactors tone generator to module adapter interface with sink API |
| src/audio/module_adapter/module_adapter.c | Propagates pipeline direction to module devices |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # A generic siggen widget. All attributes defined herein are namespaced | ||
| # by alsatplg to "Object.Widget.siggen.N.attribute_name" | ||
| # | ||
| # Usage: this component can be used by declaring int a parent object. i.e. |
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'int' to 'in'.
| # Usage: this component can be used by declaring int a parent object. i.e. | |
| # Usage: this component can be used by declaring in a parent object. i.e. |
| # Attribute categories | ||
| attributes { | ||
| # | ||
| # The sighen widget name would be constructed using the index and instance attributes. |
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected spelling of 'sighen' to 'siggen'.
| # The sighen widget name would be constructed using the index and instance attributes. | |
| # The siggen widget name would be constructed using the index and instance attributes. |
src/audio/tone.c
Outdated
| int ret; | ||
|
|
||
| /* tone generator only ever has 1 sink */ | ||
| output_frames = sink_get_free_frames(sinks[0]); |
Copilot
AI
Oct 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent array indexing. Line 395 uses sinks[0] while line 389 assigns sink = sinks[0]. Consider using the sink variable consistently throughout the function (e.g., sink_get_free_frames(sink)).
kv2019i
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question on design.
| if (dev->pipeline->direction_set) { | ||
| dev->direction_set = true; | ||
| dev->direction = dev->pipeline->direction; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ipc_comp_connect can propagates direction both ways, so shouldn't it be possible to set component directions based on "DAI copier"? The direction is passed to DAI copier already from host "get_gateway_direction(node_id.f.dma_type)", so direction is known.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kv2019i ipc_comp_connect checks both sides but the trigger is always propagated from source->sink. So if there's no host copier, the tone pipeline wont have a source direction to hinge upon
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 Right but can we extend this? Seems FW has enough information to do the right thing without any new information from host (even if it doesn't do it now).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kv2019i I dont want to extend it at all, in fact Its quite a convoluted logic having to walk through the entire pipeline just to set the component's direction. This should be simplified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 Couldn't this module be converted into some virtual/fake DAI and replace the host copier with it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 Ack. I guess this is more inline with the IPC4 philosophy of letting host provide all programming. It does still feel a bit redundant to me. The whole notion of direction is a bit redundant in describing a graph when you already provide have a description of a graph and how nodes are connected. It seems only entities that have some special functionality around playback/capture are the copier/endpoint modules and for these there's already a direction flag passed (e.g. in copier config blob). So if "direction" is only related to the endpoints, looking up the direction by traversin the graph topology, does not seem so convoluted.
| uint32_t core_id : 4; | ||
| uint32_t rsvd2 : 6; | ||
| uint32_t direction_set : 1; | ||
| uint32_t direction : 1; | ||
| uint32_t rsvd2 : 4; | ||
| uint32_t _reserved_2 : 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes in these structures require prior synchronization and acceptance from the architecture side.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tmleman ack. How do I go about this?
src/include/sof/audio/pipeline.h
Outdated
| uint32_t time_domain; /**< scheduling time domain */ | ||
| uint32_t attributes; /**< pipeline attributes from IPC extension msg/ */ | ||
| uint32_t direction_set; /**< flag indicating if direction set from IPC extension msg? */ | ||
| uint32_t direction; /**< pipeline direction from IPC extension msg */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool
src/audio/tone.c
Outdated
| dev->ipc_config = *config; | ||
| comp_info(dev, "tone_new()"); | ||
|
|
||
| cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mod_alloc() while at it to save @jsarha some work :-)
| static SHARED_DATA struct comp_driver_info comp_tone_info = { | ||
| .drv = &comp_tone, | ||
| }; | ||
| #if CONFIG_COMP_TONE_MODULE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it isn't tristate yet, it's boolean, LLEXT isn't supported for the tone generator yet, no need for this branch yet
| @@ -0,0 +1,21 @@ | |||
| #ifndef LOAD_TYPE | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is probably unneeded yet - nobody includes it
| # | ||
| ## Stream name - maps to the DAPM widget's stream name | ||
| # | ||
| DefineAttribute."stream_name" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be virtual_stream_name ? i.e. if if for virtual usage only we best name/state that so its used correctly.
The need to pass direction was discussed, I don't have strong opposition on either path, just wanted to check the options have been considered.
89e64f3 to
2ee7695
Compare
| static void tone_s32_default(struct comp_dev *dev, struct audio_stream *sink, | ||
| uint32_t frames) | ||
| static int tone_s32_passthrough(struct processing_module *mod, struct sof_sink *sink, | ||
| struct sof_source *source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does a tone generator have to support pass-through? Was it also possible with IPC3?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tone generator operates as silence generator in this case, when there is no playback happening. Silence is a kind of audio signal too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh with IPC3 we didnt have firmware based echo reference feature. This new addition to do passthrough is required for supporting that with IPC4 for SDW topologies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tone generator operates as silence generator in this case, when there is no playback happening. Silence is a kind of audio signal too.
@singalsu interesting, thanks. I think we also have ad-hoc silence generation in some components. Is it planned to remove those and use "tone" in all cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd assume those silence generator capabilities remain like now. E.g. mixin/mixout operation is defined by IPC4. While with this component with no Windows OS dependence we can define it as we need.
lgirdwood
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 feel free to fix the spelling in a subsequent PR if CI passes
a6f5ed5 to
f4bbd3a
Compare
f4bbd3a to
99f1100
Compare
99f1100 to
a94e307
Compare
| n_wrap_dest = output_end - output_pos; | ||
|
|
||
| /* Process until wrap or completed n */ | ||
| n_min = (n < n_wrap_dest) ? n : n_wrap_dest; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here a MIN() would fit perfectly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not put much effort to this. We should not have switch-case in the hot code part. The whole process function should be rewritten for better performance. I could do it later in my spare time.
src/audio/tone/tone-ipc4.c
Outdated
| /* sg->w is angle in Q4.28 radians format, sin() returns Q1.31 */ | ||
| /* sg->a is amplitude as Q1.31 */ | ||
| sine = | ||
| q_mults_32x32(sin_fixed_32b(sg->w), sg->a, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
merge with previous line please
src/audio/tone/tone-ipc4.c
Outdated
|
|
||
| if (sg->mute) | ||
| return 0; | ||
| else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else not needed
src/audio/tone/tone-ipc4.c
Outdated
| int64_t w; | ||
| /* sg->w is angle in Q4.28 radians format, sin() returns Q1.31 */ | ||
| /* sg->a is amplitude as Q1.31 */ | ||
| sine = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's checkpatch that has a habit of complaining about missing empty lines between variable declarations and code, not sure if comments make it happy though
| sg->f = (f > f_max) ? f_max : f; | ||
| /* Q16 x Q31 -> Q28 */ | ||
| w_tmp = q_multsr_32x32(sg->f, sg->c, Q_SHIFT_BITS_64(16, 31, 28)); | ||
| w_tmp = (w_tmp > PI_Q4_28) ? PI_Q4_28 : w_tmp; /* Limit to pi Q4.28 */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MIN()
| int i; | ||
|
|
||
| sg->a_target = a; | ||
| sg->a = (sg->ramp_step > sg->a_target) ? sg->a_target : sg->ramp_step; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MIN()
| */ | ||
| for (i = 0; i < TONE_NUM_FS; i++) { | ||
| if (fs == tone_fs_list[i]) | ||
| idx = i; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break?
src/audio/tone-ipc4.c
Outdated
|
|
||
| comp_info(dev, "tone_new()"); | ||
|
|
||
| cd = rzalloc(SOF_MEM_FLAG_USER, sizeof(*cd)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mod_alloc()
src/audio/tone/tone-ipc4.c
Outdated
| struct comp_data *cd = module_get_private_data(mod); | ||
| int i; | ||
|
|
||
| comp_info(mod->dev, "tone_reset()"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check and remove all function names from logs, also please try to reduce the number of *_info() level logs, e.g. this one doesn't seem to be really important
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh all of these comments above are on existing code. I will fix the mod_alloc() but Im going to leave the rest for now for the sake of consistency with the xisting code in tone.c. We can clean it up later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 not sure what this consistency brings us. If GitHub could identify that this is a copy with minor changes from tone.c and would display only a difference between the files, then yes, reducing the difference helps reviewing, but GitHub displays it as a new file, so it isn't really that helpful IMHO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok Ive fixed the logs to not contain function names now. Im going to leave the comments in the tone generator functions. @singalu will be cleaning up the tone gen functions at a later time.
a94e307 to
876c06c
Compare
|
CI now back up - rerun tests. |
|
SOFCI TEST |
|
@ranj063 There's syntax errors to fix, none of the build tests work. |
Signed-off-by: Seppo Ingalsuo <[email protected]>
Add a new implementation for the tone modeule for IPC4 with no kcontrol support as of now. This will be added later. Signed-off-by: Ranjani Sridharan <[email protected]> 1 Build fixes for tone thesofproject#10329 Signed-off-by: Seppo Ingalsuo <[email protected]>
6198b50 to
df5d2c1
Compare
All fixed now, Seppo. Thanks! |
lyakh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's IPC4-only, let's modify tone.c in place, if both IPC3 and IPC4 are supported, then Kconfig is incorrect
| default m if LIBRARY_DEFAULT_MODULAR | ||
| default y | ||
| depends on COMP_MODULE_ADAPTER | ||
| depends on IPC_MAJOR_4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it IPC4-only now? But you still have "if IPC3" code in this PR, confused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh only IPC4 is supported now. I left the IPC3 code because Daniel requested to keep it but it doesnt work and needs to be fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 ok, can we then put a comment in Kconfig, explaining, that the dependency on IPC4 is temporary and will be removed once IPC3 support is fixed? OTOH, we could also leave out this dependency and just put a comment here or in CMakeLists.txt that tone is currently broken IPC3 and just not enable it in any configurations that we're using. And if someone enables it - they'll know what they're doing. Or add a message(WARNING ...) to a cmake-file
src/audio/tone/Kconfig
Outdated
| audio tones (sine waves) at specified frequencies when the Tone | ||
| mode is enabled. The two other modes it supports are silence where | ||
| it generates 0s and passthrough where the input is passed to the output. | ||
| Warning: This component is deprecated for IPC_MAJOR_3. No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"deprecated" or "unavailable?"
src/audio/tone/tone-ipc4.c
Outdated
| struct comp_data *cd = module_get_private_data(mod); | ||
| int i; | ||
|
|
||
| comp_info(mod->dev, "tone_reset()"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 not sure what this consistency brings us. If GitHub could identify that this is a copy with minor changes from tone.c and would display only a difference between the files, then yes, reducing the difference helps reviewing, but GitHub displays it as a new file, so it isn't really that helpful IMHO
src/audio/tone/CMakeLists.txt
Outdated
| add_dependencies(app tone) | ||
| else() | ||
| if(CONFIG_IPC_MAJOR_3) | ||
| add_local_sources(sof tone.c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if IPC3 is unsupported then let's just modify it to IPC4 in-place and that would immediately help reviewing by making the diff actually display those changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
@tmleman Can you recheck? The IPC interface change is now removed from PR, I think that was the main showstopper for you. |
8832784 to
48d60ee
Compare
|
CI missing some data, looks like an issue on the test run. Will rerun. |
|
SOFCI TEST |
|
@ranj063 Fix for CI testbench build fail: |
48d60ee to
eab70ef
Compare
Add a new implementation for IPC4 for the tone module. Signed-off-by: Ranjani Sridharan <[email protected]>
Create a new conf file for the siggen module. Signed-off-by: Ranjani Sridharan <[email protected]>
Add 2 new tokens for pipeline direction and atttributes for the pipeline component. This change is required to implement the firmware based echo reference feature to inform the kernel of the pipeline direction in order for it to make a decision on which pipelines to set up when the echo reference capture pipeline is set up. The direction_valid attribute is required for backward-compatibility in the kernel driver for older topologies where the direction is not set. Signed-off-by: Ranjani Sridharan <[email protected]>
eab70ef to
a2f5b05
Compare
Preparatory patches with updates to the tone module and topology support for the tone and pipeline direction attribute.