Skip to content

Commit b7338db

Browse files
ujfalusibardliao
authored andcommitted
ASoC: SOF: ipc4-topology: Correct the process module's output lookup
The process module can change different parameters in the audio path and this change has to be properly evaluated and applied. In case of playback we are converting from multiple input formats to a single format (or just passing through without change), the output format lookup must be based on the input format. In case of capture, we are converting from a single input format to a format which is to be passed to the FE, we need to use the input parameters and the FE parameters to be able to find the correct format: for those parameters that are modified by the module instance we need to use the FE parameter while for the rest we use the input parameters. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 9d7c635 commit b7338db

1 file changed

Lines changed: 47 additions & 19 deletions

File tree

sound/soc/sof/ipc4-topology.c

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,39 +2899,69 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
28992899
if (available_fmt->num_output_formats) {
29002900
struct sof_ipc4_audio_format *in_fmt;
29012901
struct sof_ipc4_pin_format *pin_fmt;
2902-
u32 out_ref_rate, out_ref_channels;
2903-
int out_ref_valid_bits, out_ref_type;
2902+
u32 ref_rate, ref_channels;
2903+
int ref_valid_bits, ref_type;
29042904

29052905
if (available_fmt->num_input_formats) {
2906+
/*
2907+
* The process module can change parameters and their operation
2908+
* depends on the direction:
2909+
* Playback: typically they have single output format. This is
2910+
* to 'force' the conversion from input to output.
2911+
* Use the input format as reference since the single
2912+
* format is going to be picked.
2913+
* Capture: typically they have multiple output formats to
2914+
* convert from dai (input) to FE (output) parameters.
2915+
* Use the input format as base and replace the param
2916+
* which is changed by the module with the FE parameter
2917+
* Reason: we can have module which changes the
2918+
* parameters in path, we cannot use the full
2919+
* FE param set for the module output lookup.
2920+
*/
29062921
in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt;
29072922

2908-
out_ref_rate = in_fmt->sampling_frequency;
2909-
out_ref_channels =
2923+
ref_rate = in_fmt->sampling_frequency;
2924+
ref_channels =
29102925
SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg);
2911-
out_ref_valid_bits =
2926+
ref_valid_bits =
29122927
SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg);
2913-
out_ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
2928+
ref_type = sof_ipc4_fmt_cfg_to_type(in_fmt->fmt_cfg);
29142929
} else {
29152930
/* for modules without input formats, use FE params as reference */
2916-
out_ref_rate = params_rate(fe_params);
2917-
out_ref_channels = params_channels(fe_params);
2931+
ref_rate = params_rate(fe_params);
2932+
ref_channels = params_channels(fe_params);
29182933
ret = sof_ipc4_get_sample_type(sdev, fe_params);
29192934
if (ret < 0)
29202935
return ret;
2921-
out_ref_type = (u32)ret;
2936+
ref_type = (u32)ret;
29222937

2923-
out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
2924-
if (out_ref_valid_bits < 0)
2925-
return out_ref_valid_bits;
2938+
ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
2939+
if (ref_valid_bits < 0)
2940+
return ref_valid_bits;
29262941
}
29272942

2943+
if (dir == SNDRV_PCM_STREAM_CAPTURE) {
2944+
if (available_fmt->changed_params & BIT(SNDRV_PCM_HW_PARAM_RATE))
2945+
ref_rate = params_rate(fe_params);
2946+
if (available_fmt->changed_params & BIT(SNDRV_PCM_HW_PARAM_CHANNELS))
2947+
ref_channels = params_channels(fe_params);
2948+
if (available_fmt->changed_params & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) {
2949+
ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params);
2950+
if (ref_valid_bits < 0)
2951+
return ref_valid_bits;
2952+
2953+
ref_type = sof_ipc4_get_sample_type(sdev, fe_params);
2954+
if (ref_type < 0)
2955+
return ref_type;
2956+
}
2957+
}
29282958
output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget,
29292959
&process->base_config,
29302960
available_fmt,
2931-
out_ref_rate,
2932-
out_ref_channels,
2933-
out_ref_valid_bits,
2934-
out_ref_type);
2961+
ref_rate,
2962+
ref_channels,
2963+
ref_valid_bits,
2964+
ref_type);
29352965
if (output_fmt_index < 0)
29362966
return output_fmt_index;
29372967

@@ -2945,9 +2975,7 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
29452975
/* modify the pipeline params with the output format */
29462976
ret = sof_ipc4_update_hw_params(sdev, pipeline_params,
29472977
&process->output_format,
2948-
BIT(SNDRV_PCM_HW_PARAM_FORMAT) |
2949-
BIT(SNDRV_PCM_HW_PARAM_CHANNELS) |
2950-
BIT(SNDRV_PCM_HW_PARAM_RATE));
2978+
available_fmt->changed_params);
29512979
if (ret)
29522980
return ret;
29532981
}

0 commit comments

Comments
 (0)