-
Notifications
You must be signed in to change notification settings - Fork 349
Audio: Level multiplier: Add new component #10176
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
Audio: Level multiplier: Add new component #10176
Conversation
|
Still draft, I'll add HiFi3/4/5 versions using the code from volume component. However I can't use same as library since volume uses Q1.31 gain build while this is Q9.23 to have possibility for amplify. Edit - this version contains the HiFi optimizations. It can be run in sof-testbench4 and real device with generated test topologies for HDA and SDW. The default blob sets 0 dB gain and pass-through processing. The processing gain can be changed in runtime with sof-ctl with example blobs for -40 .. +40 dB. |
fb716e9 to
d06f950
Compare
d06f950 to
be9b290
Compare
be9b290 to
84f81b4
Compare
| * is used to separate the controls instances of same type. In control payload | ||
| * the num_elems defines to how many channels the control is applied to. | ||
| */ | ||
| __cold int level_multiplier_set_config(struct processing_module *mod, uint32_t param_id, |
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 don't think anybody is using __cold with IPC3, but it probably doesn't hurt either. It's only defined to something non-trivial on ACE, and ACE doesn't use IPC3
| assert_can_be_cold(); | ||
|
|
||
| comp_warn(mod->dev, "Not supported set control, type %d", cdata->cmd); | ||
| return 0; |
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.
would it work to just
#if IPC3
#define level_multiplier_set_config NULL
#define level_multiplier_get_config NULL
#endif
in a private header?
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.
Need to think this, my first try gave this:
src/audio/level_multiplier/level_multiplier.h:25:37: error: expected identifier or ‘(’ before ‘void’
25 | #define level_multiplier_set_config NULL /* No implementation for IPC3 set/get config */
| } | ||
|
|
||
| memcpy_s(&cd->gain, sizeof(int32_t), fragment, sizeof(int32_t)); | ||
| comp_info(mod->dev, "Gain set to %d", cd->gain); |
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.
would a comp_dbg() be enough?
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.
yep
| { | ||
| assert_can_be_cold(); | ||
| return 0; | ||
| } |
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.
just don't use .get_config?
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.
Yep I removed it and also removed level_multiplier-ipc3.c. I defined set_config for IPC3 build as inline dummy function. The define trick didn't build.
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.
Sorry, not following, why do we not have a get config here ? i.e. userspace will probably find it useful to know any gain or attenuation in the pipeline.
|
|
||
| comp_info(dev, "level_multiplier_init()"); | ||
|
|
||
| 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()?
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.
yes pls.
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.
Thank, I did this and next
| assert_can_be_cold(); | ||
|
|
||
| comp_dbg(mod->dev, "level_multiplier_free()"); | ||
| rfree(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_free then
|
|
||
| comp_info(dev, "level_multiplier_init()"); | ||
|
|
||
| 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.
yes pls.
4d9952c to
9548b83
Compare
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 a new level multiplier component to the audio processing pipeline that applies a configurable gain to audio signals. The component supports multiple sample formats (S16, S24, S32) with optimized implementations for different DSP architectures.
- Adds level multiplier audio component with gain configuration control
- Provides generic, HiFi3, and HiFi5 optimized implementations
- Includes pre-configured gain settings from -40dB to +40dB in 10dB increments
Reviewed Changes
Copilot reviewed 43 out of 43 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| uuid-registry.txt | Adds UUID for level multiplier component |
| tools/topology/topology2/include/components/level_multiplier.conf | Component definition for topology integration |
| tools/topology/topology2/include/components/level_multiplier/*.conf | Pre-configured gain settings (-40dB to +40dB) |
| tools/topology/topology2/include/bench/*.conf | Benchmark configuration files |
| tools/topology/topology2/cavs-benchmark-*.conf | Integration with benchmark topologies |
| tools/rimage/config/.toml | Module configuration for firmware images |
| src/audio/level_multiplier/*.c | Core implementation with format-specific processing |
| src/audio/level_multiplier/*.h | Component interfaces and data structures |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
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.
LGTM, but just one question.
| { | ||
| assert_can_be_cold(); | ||
| return 0; | ||
| } |
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.
Sorry, not following, why do we not have a get config here ? i.e. userspace will probably find it useful to know any gain or attenuation in the pipeline.
In IPC4 the kernel newer gets control value from firmware unless the firmware sends a notification to read it (currently for enum and switch, bytes support is coming). This component isn't using notification. I don't think we support the volatile control type without doing the notification. |
The reading of kcontrols is user initiated, so expectation is that level multiplier would expose a RO kcontrol for the gain/attenuation dB value. |
| struct level_multiplier_comp_data *cd = module_get_private_data(mod); | ||
| struct comp_dev *dev = mod->dev; | ||
| struct sof_source *source = sources[0]; /* One input in this example */ | ||
| struct sof_sink *sink = sinks[0]; /* One output in this example */ |
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.
Example?
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.
Oops, fixing now.
Peter is reworking the the bytes control in kernel to make the notification possible. I'll check the impacts to this component also. The FW component should work with all meaningful control access rights defined in topology. Though we may not currently support all of them in kernel. |
Level multiplier is used to set a fixed gain to stream, e.g. add +20 dB sensitivity to voice capture compared to media audio capture from the same microphone. The gain is defined by boot time set bytes control. Usually it would be set by topology. Runtime set by ALSA UCM2 is also possible usage. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This patch adds script sof_level_multiplier_blobs.m It exports blobs for -40 to +40 dB gain configuration. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This patch adds the HiFi3 and HiFi4 optimized processing. The
MCPS performance reported for stereo 48 kHz audio by:
process_test('level_multiplier', N, N, 48e3, 0, 1,
'xt-run --mem_model');
is 2.50 / 2.68 / 2.68 for S16_LE / S24_LE / S32_LE formats when
processing with non-unity gain.
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This patch adds the HiFi5 optimized processing. The MCPS performance
reported for stereo 48 kHz audio by:
process_test('level_multiplier', N, N, 48e3, 0, 1,
'xt-run --mem_model');
is 2.21 / 2.41 / 2.41 for S16_LE / S24_LE / S32_LE formats when
processing with non-unity gain.
Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This patch adds build of e.g. sof-hda-benchmark-level_multiplier32.tplg and sof-mtl-sdw-benchmark-level_multiplier32.tplg to test run the component. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
9548b83 to
36bd4b2
Compare
@singalsu @ujfalusi ok, we can follow up with the kcontrol in another PR, but this wont need a bytes kconrol. It will just need a RO volume kcontrol that shows a dB gain/attenuation. |
| Select for Level multiplier component. This component | ||
| applies a fixed gain to audio. The amount of gain | ||
| is configured in the bytes control that is typically | ||
| set in boot time from topology. It can e.g. increase | ||
| capture sensitivity of voice applications by 20 dB | ||
| compared to media capture. |
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.
btw - mix of tabs/spaces ? Not a blocker.
We don't have support for volume control change notification either. We only have Switch and Enum change support. |
We dont need a notification here as this gain will never change. This is more about telling userspace via ALSA kcontrol API that we have a gain/attenuation in this pipeline. Not a blocker to merge now, but we need this when we have the IPC4 kcontrol updates merged. |
No description provided.