1 /** 2 * @file src/aulevel.c Audio level 3 * 4 * Copyright (C) 2017 Creytiv.com 5 */ 6 7 #include <math.h> 8 #include <re.h> 9 #include <baresip.h> 10 #include "core.h" 11 12 13 /** 14 * Generic routine to calculate RMS (Root-Mean-Square) from 15 * a set of signed 16-bit values 16 * 17 * \verbatim 18 19 .--------------- 20 | N-1 21 | ----. 22 | \ 23 | \ 2 24 | | s[n] 25 | / 26 | / 27 _ | ----' 28 \ | n=0 29 \ | ------------ 30 \| N 31 32 \endverbatim 33 * 34 * @param data Array of signed 16-bit values 35 * @param len Number of values 36 * 37 * @return RMS value from 0 to 32768 38 */ calc_rms(const int16_t * data,size_t len)39static double calc_rms(const int16_t *data, size_t len) 40 { 41 double sum = 0; 42 size_t i; 43 44 if (!data || !len) 45 return .0; 46 47 for (i = 0; i < len; i++) { 48 const double sample = data[i]; 49 50 sum += sample * sample; 51 } 52 53 return sqrt(sum / (double)len); 54 } 55 56 57 /** 58 * Calculate the audio level in dBov from a set of audio samples. 59 * dBov is the level, in decibels, relative to the overload point 60 * of the system 61 * 62 * @param sampv Audio samples 63 * @param sampc Number of audio samples 64 * 65 * @return Audio level expressed in dBov 66 */ aulevel_calc_dbov(const int16_t * sampv,size_t sampc)67double aulevel_calc_dbov(const int16_t *sampv, size_t sampc) 68 { 69 static const double peak = 32767.0; 70 double rms, dbov; 71 72 if (!sampv || !sampc) 73 return AULEVEL_MIN; 74 75 rms = calc_rms(sampv, sampc) / peak; 76 77 dbov = 20 * log10(rms); 78 79 if (dbov < AULEVEL_MIN) 80 dbov = AULEVEL_MIN; 81 else if (dbov > AULEVEL_MAX) 82 dbov = AULEVEL_MAX; 83 84 return dbov; 85 } 86