Audio: Volume: Change volume internal gain to Q8.23 from Q1.23

This patch changes for IPC4 configuration the DSP internal gain
format from Q1.23 to Q8.23. Minimum needed would be Q2.23 but
the integer part 8 bits is same as in IPC3 and would allow
signal amplification in volume component in some later phase. The
code is prepared for amplification due to IPC3.

The change allows the Q1.31 max gain (0x7fffffff) to round to
exactly one in Q8.23 notation (0x800000). The gain value one passes
effectively the input to output unmodified. The change prevents lose
about 1 dB of signal-to-noise ratio from peak quality of PCM formats.

The comment from convert_volume_ipc4_to_ipc3() is removed because it
is unrelated and some remain from old code version.

The hard coded 23 for conversion to/from Qx.23 is changed to
macro VOL_QXY_Y because it's used elsewhere in the component. The
saturation (to 32 bit signed) with 64 bit intermediate is kept in
the function convert_volume_ipc4_to_ipc3() in case of VOL_QXY_Y
would be 31. The code requires int32_t or ae_f32 compatible signed
32 bit compatible gain value instead of full uint32_t range.

The gain range for Q8.23 format is min. -138.47 dB and max. +42.14 dB.

Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
This commit is contained in:
Seppo Ingalsuo 2023-05-15 16:49:06 +03:00 committed by Kai Vehmanen
parent 9b4a618c52
commit 6a08cf22df
2 changed files with 6 additions and 10 deletions

View File

@ -499,13 +499,7 @@ static int set_volume_ipc4(struct vol_data *cd, uint32_t const channel,
*/ */
static inline uint32_t convert_volume_ipc4_to_ipc3(struct comp_dev *dev, uint32_t volume) static inline uint32_t convert_volume_ipc4_to_ipc3(struct comp_dev *dev, uint32_t volume)
{ {
/* Limit received volume gain to MIN..MAX range before applying it. return sat_int32(Q_SHIFT_RND((int64_t)volume, 31, VOL_QXY_Y));
* MAX is needed for now for the generic C gain arithmetics to prevent
* multiplication overflow with the 32 bit value. Non-zero MIN option
* can be useful to prevent totally muted small volume gain.
*/
return sat_int24(Q_SHIFT_RND(volume, 31, 23));
} }
static inline uint32_t convert_volume_ipc3_to_ipc4(uint32_t volume) static inline uint32_t convert_volume_ipc3_to_ipc4(uint32_t volume)
@ -513,7 +507,7 @@ static inline uint32_t convert_volume_ipc3_to_ipc4(uint32_t volume)
/* In IPC4 volume is converted into Q1.23 format to be processed by firmware. /* In IPC4 volume is converted into Q1.23 format to be processed by firmware.
* Now convert it back to Q1.31 * Now convert it back to Q1.31
*/ */
return sat_int32(Q_SHIFT_LEFT((int64_t)volume, 23, 31)); return sat_int32(Q_SHIFT_LEFT((int64_t)volume, VOL_QXY_Y, 31));
} }
static inline void init_ramp(struct vol_data *cd, uint32_t curve_duration, uint32_t target_volume) static inline void init_ramp(struct vol_data *cd, uint32_t curve_duration, uint32_t target_volume)

View File

@ -65,8 +65,10 @@ struct sof_ipc_ctrl_value_chan;
//** \brief Volume gain Qx.y */ //** \brief Volume gain Qx.y */
#define COMP_VOLUME_Q1_23 1 #define COMP_VOLUME_Q1_23 1
//** \brief Volume gain Qx.y integer x number of bits including sign bit. */ /** \brief Volume gain Qx.y integer x number of bits including sign bit.
#define VOL_QXY_X 1 * With Q8.23 format the gain range is -138.47 to +42.14 dB.
*/
#define VOL_QXY_X 8
//** \brief Volume gain Qx.y fractional y number of bits. */ //** \brief Volume gain Qx.y fractional y number of bits. */
#define VOL_QXY_Y 23 #define VOL_QXY_Y 23