From 68e2c7c7b324cff847686b3e81e07bc26e1dfca4 Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Fri, 6 Mar 2026 20:17:54 +0200 Subject: [PATCH 1/3] Audio: Selector: Add support for multiple up/down-mix profiles This patch extends the struct ipc4_selector_coeffs_config. The first 16-bit reserved field is split into to 8-bit field for source and sink channels count. The configuration is changed to array of the previous structs instead of single. When preparing for stream the array is checked for matching number of channels for source and sink and if found the coefficients for the channels counts is selected into use. The change avoids the need for user space to update the configuration in runtime if the blob used for initialization contains all the needed channels up/down-mix profiles. Signed-off-by: Seppo Ingalsuo --- src/audio/selector/selector.c | 66 ++++++++++++++++++++++++--- src/audio/selector/selector_generic.c | 6 +-- src/include/sof/audio/selector.h | 11 ++++- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/audio/selector/selector.c b/src/audio/selector/selector.c index 40a4a2c5b888..e2e666768860 100644 --- a/src/audio/selector/selector.c +++ b/src/audio/selector/selector.c @@ -572,9 +572,9 @@ static void build_config(struct comp_data *cd, struct module_config *cfg) cd->config.out_channels_count = out_fmt->channels_count; /* Build default coefficient array (unity Q10 on diagonal, i.e. pass-through mode) */ - memset(&cd->coeffs_config, 0, sizeof(cd->coeffs_config)); + memset(cd->coeffs_config, 0, sizeof(*cd->coeffs_config)); for (i = 0; i < MIN(SEL_SOURCE_CHANNELS_MAX, SEL_SINK_CHANNELS_MAX); i++) - cd->coeffs_config.coeffs[i][i] = 1 << 10; + cd->coeffs_config->coeffs[i][i] = 1 << 10; } static int selector_init(struct processing_module *mod) @@ -620,6 +620,18 @@ static int selector_init(struct processing_module *mod) cd->sel_ipc4_cfg.init_payload_fmt = payload_fmt; md->private = cd; + /* Allocate space for max number of configurations. */ + cd->multi_coeffs_config_size = + SEL_MAX_NUM_CONFIGS * sizeof(struct ipc4_selector_coeffs_config); + cd->multi_coeffs_config = mod_zalloc(mod, cd->multi_coeffs_config_size); + if (!cd->multi_coeffs_config) { + mod_free(mod, cd); + return -ENOMEM; + } + + /* Default configuration is set to first configuration */ + cd->coeffs_config = &cd->multi_coeffs_config[0]; + if (payload_fmt == IPC4_SEL_INIT_PAYLOAD_BASE_WITH_EXT) { size_t size = sizeof(struct sof_selector_ipc4_pin_config); @@ -733,6 +745,7 @@ static int selector_free(struct processing_module *mod) comp_dbg(mod->dev, "entry"); + mod_free(mod, cd->multi_coeffs_config); mod_free(mod, cd); return 0; @@ -769,12 +782,26 @@ static int selector_set_config(struct processing_module *mod, uint32_t config_id size_t response_size) { struct comp_data *cd = module_get_private_data(mod); + int n; if (config_id == IPC4_SELECTOR_COEFFS_CONFIG_ID) { - if (data_offset_size != sizeof(cd->coeffs_config)) + if (data_offset_size > cd->multi_coeffs_config_size) { + comp_err(mod->dev, "The configuration blob is too large"); + return -EINVAL; + } + + /* The size must be N times the coefficient vectors size of one channels + * up/down mix profile. + */ + n = data_offset_size / sizeof(struct ipc4_selector_coeffs_config); + if (data_offset_size != n * sizeof(struct ipc4_selector_coeffs_config)) { + comp_err(mod->dev, "Invalid configuration size."); return -EINVAL; + } - memcpy_s(&cd->coeffs_config, sizeof(cd->coeffs_config), fragment, data_offset_size); + memcpy_s(cd->multi_coeffs_config, cd->multi_coeffs_config_size, + fragment, data_offset_size); + cd->num_configs = n; return 0; } @@ -825,7 +852,10 @@ static int selector_prepare(struct processing_module *mod, struct comp_dev *dev = mod->dev; struct comp_buffer *sinkb, *sourceb; size_t sink_size; + unsigned int source_channels; + unsigned int sink_channels; int ret; + int i; comp_dbg(dev, "entry"); @@ -855,9 +885,9 @@ static int selector_prepare(struct processing_module *mod, * proper number of channels [1] for selector to actually * reduce channel count between source and sink */ - comp_info(dev, "source sink channel = %u %u", - audio_stream_get_channels(&sourceb->stream), - audio_stream_get_channels(&sinkb->stream)); + source_channels = audio_stream_get_channels(&sourceb->stream); + sink_channels = audio_stream_get_channels(&sinkb->stream); + comp_dbg(dev, "source sink channel = %u %u", source_channels, sink_channels); sink_size = audio_stream_get_size(&sinkb->stream); @@ -891,6 +921,28 @@ static int selector_prepare(struct processing_module *mod, return -EINVAL; } + /* The first config for coefficients always exists, originating from configuration blob + * or default values (1.0) from set_selector_params(). + */ + cd->coeffs_config = cd->multi_coeffs_config; + if (cd->num_configs > 1) { + /* Use a 8ch pass-through blob if same number of channels */ + if (source_channels == sink_channels) { + source_channels = 8; + sink_channels = 8; + } + + for (i = 0; i < cd->num_configs; i++) { + if (cd->multi_coeffs_config[i].source_channels_count == source_channels && + cd->multi_coeffs_config[i].sink_channels_count == sink_channels) { + comp_info(dev, "Using coefficients for %d to %d channels.", + source_channels, sink_channels); + cd->coeffs_config = &cd->multi_coeffs_config[i]; + break; + } + } + } + return 0; } diff --git a/src/audio/selector/selector_generic.c b/src/audio/selector/selector_generic.c index 5b4d8d8f5edd..9f336536585a 100644 --- a/src/audio/selector/selector_generic.c +++ b/src/audio/selector/selector_generic.c @@ -228,7 +228,7 @@ static void sel_s16le(struct processing_module *mod, struct input_stream_buffer n = MIN(n, nmax); for (i = 0; i < n; i++) { process_frame_s16le(dest, n_chan_sink, src, n_chan_source, - &cd->coeffs_config); + cd->coeffs_config); src += audio_stream_get_channels(source); dest += audio_stream_get_channels(sink); } @@ -301,7 +301,7 @@ static void sel_s24le(struct processing_module *mod, struct input_stream_buffer n = MIN(n, nmax); for (i = 0; i < n; i++) { process_frame_s24le(dest, n_chan_sink, src, n_chan_source, - &cd->coeffs_config); + cd->coeffs_config); src += audio_stream_get_channels(source); dest += audio_stream_get_channels(sink); } @@ -372,7 +372,7 @@ static void sel_s32le(struct processing_module *mod, struct input_stream_buffer n = MIN(n, nmax); for (i = 0; i < n; i++) { process_frame_s32le(dest, n_chan_sink, src, n_chan_source, - &cd->coeffs_config); + cd->coeffs_config); src += audio_stream_get_channels(source); dest += audio_stream_get_channels(sink); } diff --git a/src/include/sof/audio/selector.h b/src/include/sof/audio/selector.h index cd4aa926c7f4..6f275271d805 100644 --- a/src/include/sof/audio/selector.h +++ b/src/include/sof/audio/selector.h @@ -43,6 +43,9 @@ struct comp_dev; /** \brief Maximum supported channel count on output. */ #define SEL_SINK_CHANNELS_MAX 8 +/** \brief Maximum number of configurations in the blob received with set_config() */ +#define SEL_MAX_NUM_CONFIGS 8 + #define SEL_NUM_IN_PIN_FMTS 1 #define SEL_NUM_OUT_PIN_FMTS 1 @@ -60,7 +63,8 @@ enum ipc4_selector_config_id { /** \brief IPC4 mixing coefficients configuration. */ struct ipc4_selector_coeffs_config { - uint16_t rsvd0; /**< Unused field, keeps the structure aligned with common layout */ + uint8_t source_channels_count; /**< source channels count when num_configs != 0 */ + uint8_t sink_channels_count; /**< sink channels count when num_configs != 0 */ uint16_t rsvd1; /**< Unused field, keeps the structure aligned with common layout */ /** Mixing coefficients in Q10 fixed point format */ @@ -108,7 +112,9 @@ typedef void (*sel_func)(struct comp_dev *dev, struct audio_stream *sink, struct comp_data { #if CONFIG_IPC_MAJOR_4 struct sof_selector_ipc4_config sel_ipc4_cfg; - struct ipc4_selector_coeffs_config coeffs_config; + struct ipc4_selector_coeffs_config *coeffs_config; + struct ipc4_selector_coeffs_config *multi_coeffs_config; + size_t multi_coeffs_config_size; #endif uint32_t source_period_bytes; /**< source number of period bytes */ @@ -117,6 +123,7 @@ struct comp_data { enum sof_ipc_frame sink_format; /**< sink frame format */ struct sof_sel_config config; /**< component configuration data */ sel_func sel_func; /**< channel selector processing function */ + int num_configs; /**< two or more if multiple mix blobs received */ }; /** \brief Selector processing functions map. */ From 4db254eed76e72f470732fd564ff69808ab4ea6d Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Mon, 9 Mar 2026 13:23:18 +0200 Subject: [PATCH 2/3] Audio: Selector: Tune: Add blob with all up/down-mix profiles This patch modifies the configuration blobs build script sof_selector_blobs.m to create one blob that contains several of them for the purpose to up or down-mix DSP offloaded decoder output. The blob uses the reserved fields of selector configuration to describe source and sink channel counts and channel config values. The exported blob is "stereo_endpoint_playback_updownmix.conf". The single configuration blobs continue to be with the reserved fields as zeros. The .conf blobs may be removed later when other topologies are modified to not use them. Signed-off-by: Seppo Ingalsuo --- src/audio/selector/tune/sof_selector_blobs.m | 160 +++++++++++++------ 1 file changed, 111 insertions(+), 49 deletions(-) diff --git a/src/audio/selector/tune/sof_selector_blobs.m b/src/audio/selector/tune/sof_selector_blobs.m index 83b38be64e3e..8ed068b35bf2 100644 --- a/src/audio/selector/tune/sof_selector_blobs.m +++ b/src/audio/selector/tune/sof_selector_blobs.m @@ -11,7 +11,7 @@ % SPDX-License-Identifier: BSD-3-Clause % -% Copyright (c) 2025, Intel Corporation. +% Copyright (c) 2025-2026, Intel Corporation. function sof_selector_blobs() @@ -19,38 +19,49 @@ function sof_selector_blobs() sof_selector_paths(true); % Matrix for 1:1 pass-through - sel.rsvd0 = 0; - sel.rsvd1 = 0; + sel.ch_count = [8 8]; % Number of channels + sel.ch_config = [12 12]; % Values of enum ipc4_channel_config: IPC4_CHANNEL_CONFIG_7_POINT_1 + sel.ch_out = 8; sel.coeffs = diag(ones(8, 1)); - write_blob(sel, "passthrough"); + passthrough_pack8 = write_blob(sel, "passthrough"); % Stereo to mono downmix + sel.ch_count = [2 1]; + sel.ch_config = [1 0]; sel.coeffs = zeros(8,8); sel.coeffs(1, 1) = 0.7071; sel.coeffs(1, 2) = 0.7071; - write_blob(sel, "downmix_stereo_to_mono"); + stereo_to_mono_pack8 = write_blob(sel, "downmix_stereo_to_mono"); % 5.1 to stereo downmix + sel.ch_count = [6 2]; + sel.ch_config = [8 1]; % IPC4_CHANNEL_CONFIG_5_POINT_1 to IPC4_CHANNEL_CONFIG_STEREO fl = 1; fr = 2; fc = 3; lfe = 4; sl = 5; sr = 6; m = zeros(8,8); m(1, fl) = 1.0000; m(1, fr) = 0.0000; m(1, fc) = 0.7071; m(1, sl) = 0.7071; m(1, sr) = 0.0000; m(2, fl) = 0.0000; m(2, fr) = 1.0000; m(2, fc) = 0.7071; m(2, sl) = 0.0000; m(2, sr) = 0.7071; sel.coeffs = m; - write_blob(sel, "downmix_51_to_stereo"); sel.coeffs(1, lfe) = 10^(+4/20); % +10 dB, attenuate by -6 dB to left sel.coeffs(2, lfe) = 10^(+4/20); % +10 dB, attenuate by -6 dB to right - write_blob(sel, "downmix_51_to_stereo_with_lfe"); + sixch_to_stereo_pack8 = write_blob(sel, "downmix_51_to_stereo_with_lfe"); % 5.1 to mono downmix + sel.ch_count = [6 1]; + sel.ch_config = [8 0]; % IPC4_CHANNEL_CONFIG_5_POINT_1 to IPC4_CHANNEL_CONFIG_MONO + sel.ch_in = 6; + sel.ch_out = 1; fl = 1; fr = 2; fc = 3; lfe = 4; sl = 5; sr = 6; m = zeros(8,8); m(1, fl) = 0.7071; m(1, fr) = 0.7071; m(1, fc) = 1.0000; m(1, sl) = 0.5000; m(1, sr) = 0.5000; sel.coeffs = m; - write_blob(sel, "downmix_51_to_mono"); sel.coeffs(1, lfe) = 10^(+10/20); - write_blob(sel, "downmix_51_to_mono_with_lfe"); + sixch_to_mono_pack8 = write_blob(sel, "downmix_51_to_mono_with_lfe"); % 7.1 to 5.1 downmix + sel.ch_count = [8 6]; + sel.ch_config = [12 8]; % IPC4_CHANNEL_CONFIG_7_POINT_1 to IPC4_CHANNEL_CONFIG_5_POINT_1 + sel.ch_in = 8; + sel.ch_out = 6; fl8 = 1; fr8 = 2; fc8 = 3; lfe8 = 4; bl8 = 5; br8 = 6; sl8 = 7; sr8 = 8; fl6 = 1; fr6 = 2; fc6 = 3; lfe6 = 4; sl6 = 5; sr6 = 6; m = zeros(8,8); @@ -63,50 +74,83 @@ function sof_selector_blobs() m(sr6, br8) = 1; m(lfe6, lfe8) = 1; sel.coeffs = m; - write_blob(sel, "downmix_71_to_51"); + eightch_to_sixch_pack8 = write_blob(sel, "downmix_71_to_51"); - % 7.1 to 5.1 downmix + % 7.1 to stereo downmix + sel.ch_count = [8 2]; + sel.ch_config = [12 1]; % IPC4_CHANNEL_CONFIG_7_POINT_1 to IPC4_CHANNEL_CONFIG_STEREO + sel.ch_in = 8; + sel.ch_out = 2; fl = 1; fr = 2; fc = 3; lfe = 4; bl = 5; br = 6; sl = 7; sr = 8; m = zeros(8,8); m(1, fl) = 1.0000; m(1, fr) = 0.0000; m(1, fc) = 0.7071; m(1, sl) = 0.7071; m(1, sr) = 0.0000; m(1, bl) = 0.7071; m(1, br) = 0.0000; m(2, fl) = 0.0000; m(2, fr) = 1.0000; m(2, fc) = 0.7071; m(2, sl) = 0.0000; m(2, sr) = 0.7071; m(2, bl) = 0.0000; m(2, br) = 0.7071; sel.coeffs = m; - write_blob(sel, "downmix_71_to_stereo"); sel.coeffs(1, lfe) = 10^(+4/20); % +10 dB, attenuate by -6 dB to left sel.coeffs(2, lfe) = 10^(+4/20); % +10 dB, attenuate by -6 dB to right - write_blob(sel, "downmix_71_to_stereo_with_lfe"); + eightch_to_stereo_pack8 = write_blob(sel, "downmix_71_to_stereo_with_lfe"); % 7.1 to mono downmix + sel.ch_count = [8 1]; + sel.ch_config = [12 0]; % IPC4_CHANNEL_CONFIG_7_POINT_1 to IPC4_CHANNEL_CONFIG_MONO + sel.ch_in = 8; + sel.ch_out = 1; fl = 1; fc = 3; fr = 2; sr = 8; br = 6; bl = 5; sl = 7; lfe = 4; m = zeros(8,8); m(1, fl) = 0.7071; m(1, fr) = 0.7071; m(1, fc) = 1.0000; m(1, sl) = 0.5000; m(1, sr) = 0.5000; m(1, bl) = 0.5000; m(1, br) = 0.5000; sel.coeffs = m; - write_blob(sel, "downmix_71_to_mono"); m(1, lfe) = 10^(+19/20); % +10 dB - write_blob(sel, "downmix_71_to_mono_with_lfe"); + eightch_to_mono_pack8 = write_blob(sel, "downmix_71_to_mono_with_lfe"); % mono to stereo upmix + sel.ch_count = [1 2]; + sel.ch_config = [0 1]; % IPC4_CHANNEL_CONFIG_MONO to IPC4_CHANNEL_CONFIG_STEREO + sel.ch_in = 1; + sel.ch_out = 2; sel.coeffs = zeros(8,8); sel.coeffs(1, 1) = 10^(-3/20); sel.coeffs(2, 1) = 10^(-3/20); - write_blob(sel, "upmix_mono_to_stereo"); + mono_to_stereo_pack8 = write_blob(sel, "upmix_mono_to_stereo"); % mono to 5.1 / 7.1 upmix - fc = 3 + sel.ch_count = [1 6]; + sel.ch_config = [0 8]; % IPC4_CHANNEL_CONFIG_MONO to IPC4_CHANNEL_CONFIG_5_POINT_1 + sel.ch_in = 1; + sel.ch_out = 6; + fc = 3; sel.coeffs = zeros(8,8); sel.coeffs(fc, 1) = 1; - write_blob(sel, "upmix_mono_to_51"); - write_blob(sel, "upmix_mono_to_71"); + mono_to_sixch_pack8 = write_blob(sel, "upmix_mono_to_51"); + sel.ch_count = [1 8]; + sel.ch_config = [0 12]; % IPC4_CHANNEL_CONFIG_MONO to IPC4_CHANNEL_CONFIG_7_POINT_1 + mono_to_eightch_pack8 = write_blob(sel, "upmix_mono_to_71"); % stereo to 5.1 / 7.1 upmix + sel.ch_count = [2 6]; + sel.ch_config = [1 8]; % IPC4_CHANNEL_CONFIG_STEREO to IPC4_CHANNEL_CONFIG_5_POINT_1 + sel.ch_in = 2; + sel.ch_out = 6; fl = 1; fr = 2; sel.coeffs = zeros(8,8); sel.coeffs(fl, 1) = 1; sel.coeffs(fr, 2) = 1; - write_blob(sel, "upmix_stereo_to_51"); - write_blob(sel, "upmix_stereo_to_71"); + stereo_to_sixch_pack8 = write_blob(sel, "upmix_stereo_to_51"); + sel.ch_count = [2 8]; + sel.ch_config = [1 12]; % IPC4_CHANNEL_CONFIG_STEREO to IPC4_CHANNEL_CONFIG_7_POINT_1 + sel.ch_in = 2; + sel.ch_out = 8; + stereo_to_eightch_pack8 = write_blob(sel, "upmix_stereo_to_71"); + + % For blob format with multiple up/down-mix profiles, intended + % for playback decoder offload conversions. + multi_pack8 = [passthrough_pack8 mono_to_stereo_pack8 sixch_to_stereo_pack8 eightch_to_stereo_pack8]; + write_8bit_packed(multi_pack8, 'stereo_endpoint_playback_updownmix'); % Stereo to L,L,R,R + sel.ch_count = [2 4]; + sel.ch_config = [13 13]; % Using IPC4_CHANNEL_CONFIG_INVALID + sel.ch_in = 2; + sel.ch_out = 4; sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... 1 0 0 0 0 0 0 0 ; ... 0 1 0 0 0 0 0 0 ; ... @@ -118,6 +162,10 @@ function sof_selector_blobs() write_blob(sel, "xover_selector_lr_to_llrr"); % Stereo to R,R,L,L + sel.ch_count = [2 4]; + sel.ch_config = [13 13]; + sel.ch_in = 2; + sel.ch_out = 4; sel.coeffs = [ 0 1 0 0 0 0 0 0 ; ... 0 1 0 0 0 0 0 0 ; ... 1 0 0 0 0 0 0 0 ; ... @@ -129,6 +177,10 @@ function sof_selector_blobs() write_blob(sel, "xover_selector_lr_to_rrll"); % Stereo to L,R,L,R + sel.ch_count = [2 4]; + sel.ch_config = [13 13]; + sel.ch_in = 2; + sel.ch_out = 4; sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... 0 1 0 0 0 0 0 0 ; ... 1 0 0 0 0 0 0 0 ; ... @@ -142,32 +194,56 @@ function sof_selector_blobs() sof_selector_paths(false); end -function write_blob(sel, blobname) +function pack8 = write_blob(sel, blobname) + pack8 = pack_selector_config(sel); + pack8_copy = pack8; + pack8_copy(1:4) = uint8([0 0 0 0]); + write_8bit_packed(pack8_copy, blobname); +end + +function write_8bit_packed(pack8, blobname) + blob8 = sof_selector_build_blob(pack8); str_config = "selector_config"; str_exported = "Exported with script sof_selector_blobs.m"; - str_howto = "cd tools/tune/selector; octave sof_selector_blobs.m" + str_howto = "cd tools/tune/selector; octave sof_selector_blobs.m"; sof_tools = '../../../../tools'; sof_tplg = fullfile(sof_tools, 'topology'); sof_tplg_selector = fullfile(sof_tplg, 'topology2/include/components/micsel'); + tplg2_fn = sprintf("%s/%s.conf", sof_tplg_selector, blobname); + sof_check_create_dir(tplg2_fn); + sof_tplg2_write(tplg2_fn, blob8, str_config, str_exported, str_howto); +end - sel +function pack8 = pack_selector_config(sel) - sum_coefs = sum(sel.coeffs, 2)' - max_sum_coef = max(sum_coefs) + sum_coefs = sum(sel.coeffs, 2)'; + max_sum_coef = max(sum_coefs); if max_sum_coef > 1 scale = 1 / max_sum_coef; else scale = 1; end - scale sel.coeffs = scale .* sel.coeffs'; + coeffs_vec = reshape(sel.coeffs, 1, []); % convert to row vector + coeffs_q10 = int16(round(coeffs_vec .* 1024)); % Q6.10 + pack8 = uint8(2 * length(coeffs_q10) + 4); + rsvd1 = 0; - blob8 = sof_selector_build_blob(sel); - tplg2_fn = sprintf("%s/%s.conf", sof_tplg_selector, blobname); - sof_check_create_dir(tplg2_fn); - sof_tplg2_write(tplg2_fn, blob8, str_config, str_exported, str_howto); -end + % header + j = 1; + pack8(j:j + 1) = uint8(sel.ch_count); + j = j + 2; + pack8(j:j + 1) = uint8(sel.ch_config); + j = j + 2; + + % coeffs matrix + for i = 1:length(coeffs_q10) + pack8(j:j+1) = int16_to_byte(coeffs_q10(i)); + j = j + 2; + end + + end function sof_selector_paths(enable) @@ -179,15 +255,11 @@ function sof_selector_paths(enable) end end -function blob8 = sof_selector_build_blob(sel) +function blob8 = sof_selector_build_blob(pack8) - s = size(sel.coeffs); blob_type = 0; blob_param_id = 0; % IPC4_SELECTOR_COEFFS_CONFIG_ID - data_length = s(1) * s(2) + 2; - data_size = 2 * data_length; % int16_t matrix - coeffs_vec = reshape(sel.coeffs, 1, []); % convert to row vector - coeffs_q10 = int16(round(coeffs_vec .* 1024)); % Q6.10 + data_size = length(pack8); ipc_ver = 4; [abi_bytes, abi_size] = sof_get_abi(data_size, ipc_ver, blob_type, blob_param_id); blob_size = data_size + abi_size; @@ -195,17 +267,7 @@ function sof_selector_paths(enable) blob8(1:abi_size) = abi_bytes; j = abi_size + 1; - % header - blob8(j:j+1) = int16_to_byte(int16(sel.rsvd0)); - j = j + 2; - blob8(j:j+1) = int16_to_byte(int16(sel.rsvd1)); - j = j + 2; - - % coeffs matrix - for i = 1:(s(1) * s(2)) - blob8(j:j+1) = int16_to_byte(coeffs_q10(i)); - j = j + 2; - end + blob8(j:j+data_size-1) = pack8; end function bytes = int16_to_byte(word) From 7dcf377bc2165e58e4f4090104acc69378290d5e Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Mon, 9 Mar 2026 19:43:00 +0200 Subject: [PATCH 3/3] Tools: Topology: Micsel: Update configuration blobs This patch adds for micsel component configuration blob "stereo_endpoint_playback_updownmix.conf". It contains the needed up-mix and down-mix coefficients to handle playback of mono, 5.1 and 7.1 channels into stereo endpoint. The old configuration blobs with five and seven channels without LFE channel are removed. Despite the file names with "51" and "71" the blobs are not suitable for 6ch or 8ch handling. Signed-off-by: Seppo Ingalsuo --- .../components/micsel/downmix_51_to_mono.conf | 26 ------- .../micsel/downmix_51_to_stereo.conf | 26 ------- .../components/micsel/downmix_71_to_mono.conf | 26 ------- .../micsel/downmix_71_to_stereo.conf | 26 ------- .../stereo_endpoint_playback_updownmix.conf | 75 +++++++++++++++++++ 5 files changed, 75 insertions(+), 104 deletions(-) delete mode 100644 tools/topology/topology2/include/components/micsel/downmix_51_to_mono.conf delete mode 100644 tools/topology/topology2/include/components/micsel/downmix_51_to_stereo.conf delete mode 100644 tools/topology/topology2/include/components/micsel/downmix_71_to_mono.conf delete mode 100644 tools/topology/topology2/include/components/micsel/downmix_71_to_stereo.conf create mode 100644 tools/topology/topology2/include/components/micsel/stereo_endpoint_playback_updownmix.conf diff --git a/tools/topology/topology2/include/components/micsel/downmix_51_to_mono.conf b/tools/topology/topology2/include/components/micsel/downmix_51_to_mono.conf deleted file mode 100644 index cd1f65b86454..000000000000 --- a/tools/topology/topology2/include/components/micsel/downmix_51_to_mono.conf +++ /dev/null @@ -1,26 +0,0 @@ -# Exported with script sof_selector_blobs.m 04-Jun-2025 -# cd tools/tune/selector; octave sof_selector_blobs.m -Object.Base.data."selector_config" { - bytes " - 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, - 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xd4,0x00,0xd4,0x00, - 0x2c,0x01,0x00,0x00,0x96,0x00,0x96,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00" -} diff --git a/tools/topology/topology2/include/components/micsel/downmix_51_to_stereo.conf b/tools/topology/topology2/include/components/micsel/downmix_51_to_stereo.conf deleted file mode 100644 index 3f7b32a251d8..000000000000 --- a/tools/topology/topology2/include/components/micsel/downmix_51_to_stereo.conf +++ /dev/null @@ -1,26 +0,0 @@ -# Exported with script sof_selector_blobs.m 04-Jun-2025 -# cd tools/tune/selector; octave sof_selector_blobs.m -Object.Base.data."selector_config" { - bytes " - 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, - 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xa8,0x01,0x00,0x00, - 0x2c,0x01,0x00,0x00,0x2c,0x01,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0xa8,0x01, - 0x2c,0x01,0x00,0x00,0x00,0x00,0x2c,0x01, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00" -} diff --git a/tools/topology/topology2/include/components/micsel/downmix_71_to_mono.conf b/tools/topology/topology2/include/components/micsel/downmix_71_to_mono.conf deleted file mode 100644 index 1e67d36bf839..000000000000 --- a/tools/topology/topology2/include/components/micsel/downmix_71_to_mono.conf +++ /dev/null @@ -1,26 +0,0 @@ -# Exported with script sof_selector_blobs.m 04-Jun-2025 -# cd tools/tune/selector; octave sof_selector_blobs.m -Object.Base.data."selector_config" { - bytes " - 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, - 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xa4,0x00,0xa4,0x00, - 0xe8,0x00,0x00,0x00,0x74,0x00,0x74,0x00, - 0x74,0x00,0x74,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00" -} diff --git a/tools/topology/topology2/include/components/micsel/downmix_71_to_stereo.conf b/tools/topology/topology2/include/components/micsel/downmix_71_to_stereo.conf deleted file mode 100644 index df6af38dde34..000000000000 --- a/tools/topology/topology2/include/components/micsel/downmix_71_to_stereo.conf +++ /dev/null @@ -1,26 +0,0 @@ -# Exported with script sof_selector_blobs.m 04-Jun-2025 -# cd tools/tune/selector; octave sof_selector_blobs.m -Object.Base.data."selector_config" { - bytes " - 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, - 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x48,0x01,0x00,0x00, - 0xe8,0x00,0x00,0x00,0xe8,0x00,0x00,0x00, - 0xe8,0x00,0x00,0x00,0x00,0x00,0x48,0x01, - 0xe8,0x00,0x00,0x00,0x00,0x00,0xe8,0x00, - 0x00,0x00,0xe8,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00" -} diff --git a/tools/topology/topology2/include/components/micsel/stereo_endpoint_playback_updownmix.conf b/tools/topology/topology2/include/components/micsel/stereo_endpoint_playback_updownmix.conf new file mode 100644 index 000000000000..70500ef0e0fa --- /dev/null +++ b/tools/topology/topology2/include/components/micsel/stereo_endpoint_playback_updownmix.conf @@ -0,0 +1,75 @@ +# Exported with script sof_selector_blobs.m 10-Mar-2026 +# cd tools/tune/selector; octave sof_selector_blobs.m +Object.Base.data."selector_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x10,0x02,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x08,0x08,0x0c,0x0c,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x04,0x01,0x02,0x00,0x01, + 0xd5,0x02,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xd5,0x02,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x06,0x02,0x08,0x01,0x00,0x01,0x00,0x00, + 0xb5,0x00,0x96,0x01,0xb5,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0xb5,0x00,0x96,0x01,0x00,0x00,0xb5,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x08,0x02,0x0c,0x01, + 0xda,0x00,0x00,0x00,0x9a,0x00,0x59,0x01, + 0x9a,0x00,0x00,0x00,0x9a,0x00,0x00,0x00, + 0x00,0x00,0xda,0x00,0x9a,0x00,0x59,0x01, + 0x00,0x00,0x9a,0x00,0x00,0x00,0x9a,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00" +}