Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 31 additions & 5 deletions src/audio/volume/volume.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,13 @@ static void volume_ramp(struct comp_dev *dev)
*/
cd->vol_ramp_active = true;

/* Current ramp time in milliseconds */
ramp_time = cd->vol_ramp_elapsed_frames * 1000 / cd->sample_rate;
/* Current ramp time in Q29.3 milliseconds. Note that max. ramp length
* can be 1.3s at 192 kHz rate and 5.5s at 48 kHz rate without
* exceeding int32_t range. Value 8000 is 1000 for converting to
* milliseconds times 8 (2 ^ 3) for fraction.
*/
ramp_time = cd->vol_ramp_elapsed_frames * 8000 / cd->sample_rate;


/* Update each volume if it's not at target for active channels */
for (i = 0; i < cd->channels; i++) {
Expand Down Expand Up @@ -462,7 +467,12 @@ static inline int volume_set_chan(struct comp_dev *dev, int chan,
coef = delta_abs;
}

/* Ensure ramp coefficient is at least min. non-zero Q16.16 */
/* Scale coefficient by 1/8, round */
coef = ((coef >> 2) + 1) >> 1;

/* Ensure ramp coefficient is at least min. non-zero
* fractional value.
*/
coef = MAX(coef, 1);

/* Invert sign for volume down ramp step */
Expand Down Expand Up @@ -779,9 +789,11 @@ static int volume_prepare(struct comp_dev *dev)
struct comp_data *cd = comp_get_drvdata(dev);
struct comp_buffer *sinkb;
struct sof_ipc_comp_config *config = dev_comp_config(dev);
struct sof_ipc_comp_volume *pga;
uint32_t sink_period_bytes;
int i;
int ramp_update_us;
int ret;
int i;

comp_dbg(dev, "volume_prepare()");

Expand Down Expand Up @@ -830,7 +842,6 @@ static int volume_prepare(struct comp_dev *dev)
* for entire topology specified time.
*/
cd->ramp_finished = true;
cd->vol_ramp_frames = dev->frames / (dev->period / VOL_RAMP_UPDATE_US);
cd->channels = sinkb->stream.channels;
cd->sample_rate = sinkb->stream.rate;
for (i = 0; i < cd->channels; i++) {
Expand All @@ -840,6 +851,21 @@ static int volume_prepare(struct comp_dev *dev)
cd->ramp_finished = false;
}

/* Determine ramp update rate depending on requested ramp length. To
* ensure evenly updated gain envelope with limited fraction resolution
* four presets are used.
*/
pga = COMP_GET_IPC(dev, sof_ipc_comp_volume);
if (pga->initial_ramp < VOL_RAMP_UPDATE_THRESHOLD_FASTEST_MS)
ramp_update_us = VOL_RAMP_UPDATE_FASTEST_US;
else if (pga->initial_ramp < VOL_RAMP_UPDATE_THRESHOLD_FAST_MS)
ramp_update_us = VOL_RAMP_UPDATE_FAST_US;
else if (pga->initial_ramp < VOL_RAMP_UPDATE_THRESHOLD_SLOW_MS)
ramp_update_us = VOL_RAMP_UPDATE_SLOW_US;
else
ramp_update_us = VOL_RAMP_UPDATE_SLOWEST_US;

cd->vol_ramp_frames = dev->frames / (dev->period / ramp_update_us);
return 0;

err:
Expand Down
14 changes: 12 additions & 2 deletions src/include/sof/audio/volume.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,19 @@ struct sof_ipc_ctrl_value_chan;

/**
* \brief Volume ramp update rate in microseconds.
* Update volume gain value every 1 ms.
* Update volume gain value every 125 to 1000 us. The faster gain ramps need
* higher update rate to avoid annoying zipper noise sound. The below
* values were tested subjectively for constraint of 125 microseconds
* multiple gain update rate.
*/
#define VOL_RAMP_UPDATE_US 1000
#define VOL_RAMP_UPDATE_SLOWEST_US 1000
#define VOL_RAMP_UPDATE_SLOW_US 500
#define VOL_RAMP_UPDATE_FAST_US 250
#define VOL_RAMP_UPDATE_FASTEST_US 125

#define VOL_RAMP_UPDATE_THRESHOLD_SLOW_MS 128
#define VOL_RAMP_UPDATE_THRESHOLD_FAST_MS 64
#define VOL_RAMP_UPDATE_THRESHOLD_FASTEST_MS 32

/**
* \brief Volume maximum value.
Expand Down
4 changes: 2 additions & 2 deletions tools/topology/sof/pipe-asrc-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ W_ASRC(0, PIPELINE_FORMAT, 2, 2, MY_ASRC_CONF)
define(MY_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(MY_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))
W_VENDORTUPLES(MY_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))
W_DATA(MY_PGA_CONF, MY_PGA_TOKENS)

# "Volume" has x sink and 2 source periods
Expand Down
4 changes: 2 additions & 2 deletions tools/topology/sof/pipe-dcblock-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ C_CONTROLMIXER(Master Playback Volume, PIPELINE_ID,
define(MY_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(MY_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))
W_VENDORTUPLES(MY_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(MY_PGA_CONF, MY_PGA_TOKENS)

Expand Down
4 changes: 2 additions & 2 deletions tools/topology/sof/pipe-eq-fir-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ define(DEF_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(DEF_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))

W_VENDORTUPLES(DEF_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(DEF_PGA_CONF, DEF_PGA_TOKENS)

Expand Down
4 changes: 2 additions & 2 deletions tools/topology/sof/pipe-eq-iir-eq-fir-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ define(DEF_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(DEF_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))

W_VENDORTUPLES(DEF_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(DEF_PGA_CONF, DEF_PGA_TOKENS)

Expand Down
4 changes: 2 additions & 2 deletions tools/topology/sof/pipe-eq-iir-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ define(DEF_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(DEF_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))

W_VENDORTUPLES(DEF_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(DEF_PGA_CONF, DEF_PGA_TOKENS)

Expand Down
14 changes: 9 additions & 5 deletions tools/topology/sof/pipe-src-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,17 @@ W_SRC(0, PIPELINE_FORMAT, 3, 3, media_src_conf)
# Volume Configuration
#

W_VENDORTUPLES(playback_pga_tokens, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
define(DEF_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(DEF_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))

W_VENDORTUPLES(DEF_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(playback_pga_conf, playback_pga_tokens)
W_DATA(DEF_PGA_CONF, DEF_PGA_TOKENS)

# "Volume" has 3 source and x sink periods
W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 3, playback_pga_conf, SCHEDULE_CORE,
W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 3, DEF_PGA_CONF, SCHEDULE_CORE,
LIST(` ', "PIPELINE_ID Master Playback Volume"))

# Playback Buffers
Expand Down Expand Up @@ -96,3 +98,5 @@ indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), SRC Playback PCM_ID)

PCM_CAPABILITIES(SRC Playback PCM_ID, `S32_LE,S24_LE,S16_LE', 8000, 192000, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536)

undefine(`DEF_PGA_TOKENS')
undefine(`DEF_PGA_CONF')
15 changes: 10 additions & 5 deletions tools/topology/sof/pipe-volume-playback.m4
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@ C_CONTROLMIXER(Master Playback Volume, PIPELINE_ID,
# Volume configuration
#

W_VENDORTUPLES(playback_pga_tokens, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"'))
define(DEF_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID))
define(DEF_PGA_CONF, concat(`pga_conf_', PIPELINE_ID))

W_DATA(playback_pga_conf, playback_pga_tokens)
W_VENDORTUPLES(DEF_PGA_TOKENS, sof_volume_tokens,
LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "2"'
` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "20"'))

W_DATA(DEF_PGA_CONF, DEF_PGA_TOKENS)

#
# Components and Buffers
Expand All @@ -44,7 +47,7 @@ W_DATA(playback_pga_conf, playback_pga_tokens)
W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, 2, 0, SCHEDULE_CORE)

# "Volume" has 2 source and x sink periods
W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 2, playback_pga_conf, SCHEDULE_CORE,
W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 2, DEF_PGA_CONF, SCHEDULE_CORE,
LIST(` ', "PIPELINE_ID Master Playback Volume"))

# Playback Buffers
Expand Down Expand Up @@ -79,3 +82,5 @@ indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_I
#
PCM_CAPABILITIES(Passthrough Playback PCM_ID, `S32_LE,S24_LE,S16_LE', PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536)

undefine(`DEF_PGA_TOKENS')
undefine(`DEF_PGA_CONF')