From: Jean Aunis Date: Tue, 7 Apr 2020 12:05:22 +0000 (+0200) Subject: func_volume: Accept decimal number as argument X-Git-Tag: 13.33.0-rc1~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=947a6e8674794eb5b686e2da5d9a0216c5bfc798;p=thirdparty%2Fasterisk.git func_volume: Accept decimal number as argument Allow voice volume to be multiplied or divided by a floating point number. ASTERISK-28813 Change-Id: I5b42b890ec4e1f6b0b3400cb44ff16522b021c8c --- diff --git a/doc/CHANGES-staging/func_volume.txt b/doc/CHANGES-staging/func_volume.txt new file mode 100644 index 0000000000..e73295b99a --- /dev/null +++ b/doc/CHANGES-staging/func_volume.txt @@ -0,0 +1,3 @@ +Subject: func_volume + +Accept decimal number as argument. diff --git a/funcs/func_volume.c b/funcs/func_volume.c index f381c413b2..438d9a2155 100644 --- a/funcs/func_volume.c +++ b/funcs/func_volume.c @@ -72,8 +72,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") struct volume_information { struct ast_audiohook audiohook; - int tx_gain; - int rx_gain; + float tx_gain; + float rx_gain; unsigned int flags; }; @@ -109,7 +109,7 @@ static int volume_callback(struct ast_audiohook *audiohook, struct ast_channel * { struct ast_datastore *datastore = NULL; struct volume_information *vi = NULL; - int *gain = NULL; + float *gain = NULL; /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */ if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) @@ -143,7 +143,7 @@ static int volume_callback(struct ast_audiohook *audiohook, struct ast_channel * if (!(gain = (direction == AST_AUDIOHOOK_DIRECTION_READ) ? &vi->rx_gain : &vi->tx_gain) || !*gain) return 0; /* Apply gain to frame... easy as pi */ - ast_frame_adjust_volume(frame, *gain); + ast_frame_adjust_volume_float(frame, *gain); } return 0; @@ -195,9 +195,9 @@ static int volume_write(struct ast_channel *chan, const char *cmd, char *data, c } if (!strcasecmp(args.direction, "tx")) { - vi->tx_gain = atoi(value); + vi->tx_gain = atof(value); } else if (!strcasecmp(args.direction, "rx")) { - vi->rx_gain = atoi(value); + vi->rx_gain = atof(value); } else { ast_log(LOG_ERROR, "Direction must be either RX or TX\n"); } diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index 9733600f00..4572b6e122 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -587,6 +587,14 @@ struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, */ int ast_frame_adjust_volume(struct ast_frame *f, int adjustment); +/*! + \brief Adjusts the volume of the audio samples contained in a frame. + \param f The frame containing the samples (must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR) + \param adjustment The number of dB to adjust up or down. + \return 0 for success, non-zero for an error + */ +int ast_frame_adjust_volume_float(struct ast_frame *f, float adjustment); + /*! \brief Sums two frames of audio samples. \param f1 The first frame (which will contain the result) diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index 2e652c35ee..082cec4ed7 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -375,11 +375,35 @@ static force_inline void ast_slinear_saturated_multiply(short *input, short *val *input = (short) res; } +static force_inline void ast_slinear_saturated_multiply_float(short *input, float *value) +{ + float res; + + res = (float) *input * *value; + if (res > 32767) + *input = 32767; + else if (res < -32768) + *input = -32768; + else + *input = (short) res; +} + static force_inline void ast_slinear_saturated_divide(short *input, short *value) { *input /= *value; } +static force_inline void ast_slinear_saturated_divide_float(short *input, float *value) +{ + float res = (float) *input / *value; + if (res > 32767) + *input = 32767; + else if (res < -32768) + *input = -32768; + else + *input = (short) res; +} + #ifdef localtime_r #undef localtime_r #endif diff --git a/main/frame.c b/main/frame.c index 6dc28a70da..28178a6309 100644 --- a/main/frame.c +++ b/main/frame.c @@ -45,6 +45,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/dsp.h" #include "asterisk/file.h" +#include + #if !defined(LOW_MEMORY) static void frame_cache_cleanup(void *data); @@ -695,6 +697,31 @@ int ast_frame_adjust_volume(struct ast_frame *f, int adjustment) return 0; } +int ast_frame_adjust_volume_float(struct ast_frame *f, float adjustment) +{ + int count; + short *fdata = f->data.ptr; + float adjust_value = fabs(adjustment); + + if ((f->frametype != AST_FRAME_VOICE) || !(ast_format_cache_is_slinear(f->subclass.format))) { + return -1; + } + + if (!adjustment) { + return 0; + } + + for (count = 0; count < f->samples; count++) { + if (adjustment > 0) { + ast_slinear_saturated_multiply_float(&fdata[count], &adjust_value); + } else if (adjustment < 0) { + ast_slinear_saturated_divide_float(&fdata[count], &adjust_value); + } + } + + return 0; +} + int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2) { int count;