diff --git a/src/audio/volume/volume.c b/src/audio/volume/volume.c index 37c6ad05040b..2c7d83b1fcc4 100644 --- a/src/audio/volume/volume.c +++ b/src/audio/volume/volume.c @@ -243,6 +243,24 @@ static inline int32_t volume_windows_fade_ramp(struct vol_data *cd, int32_t ramp } #endif +void volume_set_ramp_channel(struct vol_data *cd, uint32_t channels_count) +{ + int i; + + cd->is_same_volume = true; + for (i = 1; i < channels_count; i++) { + if (cd->tvolume[0] != cd->tvolume[i]) { + cd->is_same_volume = false; + break; + } + } + + if (cd->is_same_volume) + cd->ramp_channel_counter = 1; + else + cd->ramp_channel_counter = channels_count; +} + /** * \brief Ramps volume changes over time. * \param[in,out] vol_data Volume component data @@ -272,7 +290,7 @@ static inline void volume_ramp(struct processing_module *mod) #endif /* Update each volume if it's not at target for active channels */ - for (i = 0; i < cd->channels; i++) { + for (i = 0; i < cd->ramp_channel_counter; i++) { /* skip if target reached */ volume = cd->volume[i]; tvolume = cd->tvolume[i]; @@ -311,6 +329,11 @@ static inline void volume_ramp(struct processing_module *mod) cd->volume[i] = new_vol; } + if (cd->is_same_volume) { + for (i = 1; i < cd->channels; i++) + cd->volume[i] = cd->volume[0]; + } + cd->is_passthrough = cd->ramp_finished; for (i = 0; i < cd->channels; i++) { if (cd->volume[i] != VOL_ZERO_DB) { diff --git a/src/audio/volume/volume.h b/src/audio/volume/volume.h index 140ec3e7af2f..b1c2bb18c817 100644 --- a/src/audio/volume/volume.h +++ b/src/audio/volume/volume.h @@ -176,6 +176,8 @@ struct vol_data { bool copy_gain; /**< control copy gain or not */ uint32_t attenuation; /**< peakmeter adjustment in range [0 - 31] */ bool is_passthrough; /**< is passthrough or do gain multiplication */ + bool is_same_volume; /**< check ramp volume are same with each channel */ + uint32_t ramp_channel_counter; /**< channels need new ramp volume */ }; /** \brief Volume processing functions map. */ @@ -308,4 +310,6 @@ void volume_set_chan_mute(struct processing_module *mod, int chan); void volume_set_chan_unmute(struct processing_module *mod, int chan); +void volume_set_ramp_channel(struct vol_data *cd, uint32_t channels_count); + #endif /* __SOF_AUDIO_VOLUME_H__ */ diff --git a/src/audio/volume/volume_ipc3.c b/src/audio/volume/volume_ipc3.c index 3881c4ae7f8b..9514a8c16af9 100644 --- a/src/audio/volume/volume_ipc3.c +++ b/src/audio/volume/volume_ipc3.c @@ -149,6 +149,10 @@ int volume_init(struct processing_module *mod) cd->muted[i] = false; } + cd->is_same_volume = true; + /* all target volume are same */ + cd->ramp_channel_counter = 1; + switch (cd->ramp_type) { #if CONFIG_COMP_VOLUME_LINEAR_RAMP case SOF_VOLUME_LINEAR: @@ -221,6 +225,7 @@ int volume_set_config(struct processing_module *mod, uint32_t config_id, return ret; } } + volume_set_ramp_channel(cd, cd->channels); volume_ramp_check(mod); break; diff --git a/src/audio/volume/volume_ipc4.c b/src/audio/volume/volume_ipc4.c index 07ac8af63a9b..f246792c2d1e 100644 --- a/src/audio/volume/volume_ipc4.c +++ b/src/audio/volume/volume_ipc4.c @@ -156,6 +156,7 @@ int volume_init(struct processing_module *mod) } md->private = cd; + cd->is_same_volume = true; for (channel = 0; channel < channels_count; channel++) { if (vol->config[0].channel_id == IPC4_ALL_CHANNELS_MASK) @@ -174,6 +175,8 @@ int volume_init(struct processing_module *mod) init_ramp(cd, vol->config[0].curve_duration, target_volume[0]); + volume_set_ramp_channel(cd, channels_count); + cd->mailbox_offset = offsetof(struct ipc4_fw_registers, peak_vol_regs); cd->mailbox_offset += instance_id * sizeof(struct ipc4_peak_volume_regs); @@ -256,6 +259,8 @@ static int volume_set_volume(struct processing_module *mod, const uint8_t *data, } } + volume_set_ramp_channel(cd, channels_count); + cd->scale_vol = vol_get_processing_function(dev, cd); volume_prepare_ramp(dev, cd);