Skip to content

audio: eq_iir: tune: add sof_ucm2_eq_generate#10980

Open
singalsu wants to merge 2 commits into
thesofproject:mainfrom
singalsu:add_sof_ucm2_eq_generate
Open

audio: eq_iir: tune: add sof_ucm2_eq_generate#10980
singalsu wants to merge 2 commits into
thesofproject:mainfrom
singalsu:add_sof_ucm2_eq_generate

Conversation

@singalsu

@singalsu singalsu commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

This patch adds an automatic UCMv2 configuration generator for SOF equalizers. An example speaker speaker demo case can be run:

>> sof_ucm2_eq_generate('example', 'example', 'speaker', 'sof_ucm2_eq_example.xlsx');
Averaged 2 response columns from sof_ucm2_eq_example.xlsx
Stage 1 (very-low-Q PN2): fc=2500.3 Hz  g=-7.48 dB  Q=0.50
Stage 2 bass gain upper bound = 12.00 dB (mid atten -7.48 dB, cap 26.0 dB)
Stage 2 (LS2): fc=237.8 Hz  g=12.00 dB
Stage 3 (fine PN2 #1): fc=322.7 Hz  g=-6.00 dB  Q=0.10
Stage 4 (fine PN2 #2): fc=9043.7 Hz  g=12.00 dB  Q=1.00
FIR: length=63 taps, mid band [400, 12000] Hz
Blob size is 240 bytes.
03 00 00 00 e8 00 00 00 53 4f 46 34 00 00 00 00
c8 00 00 00 01 d0 01 03 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 c8 00 00 00 02 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00
05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 2b f3 5a ea 48 2f 19 51 45 73 e4 14
77 19 37 d6 45 73 e4 14 00 00 00 00 00 40 00 00
f9 1a 67 dd 7a 62 82 62 6b d8 03 15 18 de a0 ce
9b 91 66 1c 00 00 00 00 00 40 00 00 50 da f0 c0
1e 5d 0d 7f 81 bd dd 00 ba 0f 31 fe 9a 17 f2 00
00 00 00 00 00 40 00 00 d5 97 c1 c2 11 e0 2e 7d
da 79 00 00 11 48 fb ff da 06 0c 00 00 00 00 00
00 40 00 00 a4 f3 1b d8 88 3c 35 27 38 16 1e 07
20 a1 f5 ee 41 d6 e0 0a ea ff ff ff 8d 4b 00 00

Note: Filter length was reduced to 64 -> 60 due to trailing zeros.
Note: Filter length is 60
Blob size is 208 bytes.
03 00 00 00 c8 00 00 00 53 4f 46 34 00 00 00 00
a8 00 00 00 01 d0 01 03 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 a8 00 00 00 02 00 01 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 3c 00 ff ff 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 42 48 2f fa 09 f4 19 f8
df 05 91 0e 82 07 5d f9 c2 f5 fa ff 7a 09 c6 06
07 fe c9 fb fa 00 0c 04 17 00 ac fa 9a fa 22 ff
90 02 f6 01 88 ff 96 fe 9e ff b9 00 8b 00 ac ff
52 ff b0 ff 16 00 1a 00 f4 ff f0 ff 03 00 02 00
ed ff dd ff df ff e8 ff f2 ff fc ff 08 00 11 00
14 00 12 00 0f 00 0d 00 0b 00 07 00 05 00 05 00
04 00 03 00 02 00 01 00 01 00 01 00 01 00 00 00

Wrote ucm2_blobs_sof/product_configs/example/example.conf

It produces for automatic DMI ID names based inclusion to UCM2 the configuration:

$ cat ucm2_blobs_sof/product_configs/example/example.conf
# Add bespoke speaker equalizer for example example
#
# IIR is defined as parametric equalizer and FIR carries the mid-band residual
# correction, see:
# https://github.com/thesofproject/sof/tree/main/src/audio/eq_iir/tune
#
#	PEQ_HP2      80.0   +0.0  0.00
#	PEQ_PN2    2500.3   -7.5  0.50
#	PEQ_LS2     237.8  +12.0  0.00
#	PEQ_PN2     322.7   -6.0  0.10
#	PEQ_PN2    9043.7  +12.0  1.00

Define.PostMixerSpeakerPlaybackIirBlob "/usr/share/alsa/ucm2/blobs/sof/ipc4/eq_iir/speaker_example_example_iir.bin"
Define.PostMixerSpeakerPlaybackFirBlob "/usr/share/alsa/ucm2/blobs/sof/ipc4/eq_fir/speaker_example_example_fir.bin"


The graphical output from Octave can be used for visual check for sane design:

Screenshot From 2026-07-08 14-30-47

Add two small example endpoint frequency-response measurements so
the sof_ucm2_eq_generate script added in the following commit can
be exercised without external input:

  sof_ucm2_eq_example.txt   1024x3 (freq Hz, response L, response R)
  sof_ucm2_eq_example.xlsx  identical numeric grid in Excel form

Both files share the same [frequency, magnitude...] layout the
loader expects, so they also demonstrate the multi-column
averaging code path.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
@singalsu singalsu marked this pull request as ready for review July 8, 2026 11:37
Copilot AI review requested due to automatic review settings July 8, 2026 11:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Octave-based generator that fits a combined IIR+FIR EQ from measurement data and emits both SOF IPC4 EQ blobs and a corresponding UCMv2 include file for automatic product config inclusion.

Changes:

  • Introduce sof_ucm2_eq_generate() to load measurements, fit a constrained multi-stage IIR, design a short mid-band FIR residual corrector, and export IPC4 blobs + UCM .conf.
  • Add a sample comma-separated measurement dataset (sof_ucm2_eq_example.txt) intended for demonstrating/validating the generator workflow.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/audio/eq_iir/tune/sof_ucm2_eq_generate.m New Octave function to generate IPC4 EQ blobs and a UCMv2 include from measurement data.
src/audio/eq_iir/tune/sof_ucm2_eq_example.txt Example CSV-like measurement input for the generator.

Comment thread src/audio/eq_iir/tune/sof_ucm2_eq_generate.m Outdated
Comment thread src/audio/eq_iir/tune/sof_ucm2_eq_generate.m

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

Comment thread src/audio/eq_iir/tune/sof_ucm2_eq_generate.m
Comment thread src/audio/eq_iir/tune/sof_ucm2_eq_generate.m Outdated
Comment thread src/audio/eq_iir/tune/sof_ucm2_eq_generate.m Outdated
@singalsu singalsu requested review from kv2019i and lgirdwood July 8, 2026 14:02
@singalsu

singalsu commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Some issue with the UCM bin blob -> draft

@singalsu singalsu marked this pull request as draft July 8, 2026 14:51
Add a tuning script that turns a measured endpoint frequency
response into a pair of IIR + FIR blobs and a UCM2 include file
laid out the way alsa-ucm-conf expects. The IIR is a four-biquad
parametric (HP2 + low-Q mid PN2 + LS2 + one fine PN2 corrector)
fit stage-by-stage with fminsearch, and the residual mid-band
delta is picked up by a short minimum-phase FIR.

The script takes the DMI sys_vendor and product_name from
/sys/devices/virtual/dmi/id and an endpoint name, and produces:

  ucm2_blobs_sof/ipc4/eq_iir/<endpoint>_<vendor>_<product>_iir.{txt,bin}
  ucm2_blobs_sof/ipc4/eq_fir/<endpoint>_<vendor>_<product>_fir.{txt,bin}
  ucm2_blobs_sof/product_configs/<SYS_VENDOR>/<PRODUCT_NAME>.conf

The blob file names are lowercased and non-alphanumeric runs are
folded to underscores; the vendor and product directory names are
kept verbatim to match the existing alsa-ucm-conf tree. The .conf
file follows the alsa-ucm-conf sof/product_configs style with a
biquad summary in comments and the two
Define.PostMixer<Endpoint>Playback{Iir,Fir}Blob keys pointing at the
installed /usr/share/alsa/ucm2/blobs/sof/... paths.

Measurement input is a numeric grid with column 1 = frequency in
Hz and one or more magnitude columns in dB that are averaged.
Plain text and Excel/ODS workbooks are both accepted, dispatched
by file extension. The sof_ucm2_eq_example.{txt,xlsx} files added
in the previous commit let the script be run without external
data:

  sof_ucm2_eq_generate('example', 'example', 'speaker', \
                       'sof_ucm2_eq_example.txt');
  sof_ucm2_eq_generate('example', 'example', 'speaker', \
                       'sof_ucm2_eq_example.xlsx');

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
@singalsu singalsu force-pushed the add_sof_ucm2_eq_generate branch from 8e3cb46 to a14e7df Compare July 8, 2026 17:15
@singalsu singalsu marked this pull request as ready for review July 8, 2026 17:16
@singalsu singalsu requested a review from Copilot July 8, 2026 17:16
@singalsu

singalsu commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator Author

Sounds good now, draft --> proposal.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

Comment on lines +99 to +103
%% Parametric target: keep the corrected response band-limited so the fit
%% does not chase noise below 100 Hz (below the speaker's useful range) or
%% brighten the top octave. HP2 100 Hz rolls off sub-bass in the target,
%% LP2 15 kHz tames the highs. Both the IIR stage fit (stage_rms) and the
%% FIR design in sof_eq_compute honor eq.t_db that this generates.
% Params: [fc, gain, Q]. fc [2000, 4000] Hz, gain [-12, +6] dB, Q [0.5, 1.0].
fmin_fit = 400;
fmax_fit = 7000;
p1_0 = [2500, -6, 0.4];
Comment on lines +260 to +267
eq.fir_length = 63;
eq.fir_beta = 10;
eq.fir_minph = 1;
eq.fir_autoband = 0;
eq.fmin_fir = 400;
eq.fmax_fir = 7000;
fprintf('FIR: length=%d taps, mid band [%d, %d] Hz\n', ...
eq.fir_length, eq.fmin_fir, eq.fmax_fir);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants