Changeset 228 for pjproject/trunk/pjmedia/src/pjmedia/silencedet.c
- Timestamp:
- Feb 25, 2006 2:04:42 AM (18 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/silencedet.c
r222 r228 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 #include <pjmedia/ vad.h>19 #include <pjmedia/silencedet.h> 20 20 #include <pjmedia/errno.h> 21 21 #include <pj/assert.h> … … 24 24 25 25 26 #define THIS_FILE " vad.c"27 28 typedef enum pjmedia_ vad_mode {26 #define THIS_FILE "silencedet.c" 27 28 typedef enum pjmedia_silence_det_mode { 29 29 VAD_MODE_NONE, 30 30 VAD_MODE_FIXED, 31 31 VAD_MODE_ADAPTIVE 32 } pjmedia_ vad_mode;32 } pjmedia_silence_det_mode; 33 33 34 34 35 35 /** 36 * This structure holds the vadstate.36 * This structure holds the silence detector state. 37 37 */ 38 struct pjmedia_ vad38 struct pjmedia_silence_det 39 39 { 40 40 int mode; /**< VAD mode. */ … … 60 60 61 61 62 PJ_DEF(pj_status_t) pjmedia_ vad_create( pj_pool_t *pool,63 pjmedia_vad **p_vad)64 { 65 pjmedia_ vad *vad;66 67 PJ_ASSERT_RETURN(pool && p_ vad, PJ_EINVAL);68 69 vad = pj_pool_zalloc(pool, sizeof(struct pjmedia_vad));70 71 vad->weakest_signal = 0xFFFFFFFFUL;72 vad->loudest_silence = 0;73 vad->signal_cnt = 0;74 vad->silence_cnt = 0;62 PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 63 pjmedia_silence_det **p_sd) 64 { 65 pjmedia_silence_det *sd; 66 67 PJ_ASSERT_RETURN(pool && p_sd, PJ_EINVAL); 68 69 sd = pj_pool_zalloc(pool, sizeof(struct pjmedia_silence_det)); 70 71 sd->weakest_signal = 0xFFFFFFFFUL; 72 sd->loudest_silence = 0; 73 sd->signal_cnt = 0; 74 sd->silence_cnt = 0; 75 75 76 76 /* Restart in adaptive, silent mode */ 77 vad->in_talk = PJ_FALSE;78 pjmedia_ vad_set_adaptive( vad, 160 );79 80 *p_ vad = vad;81 return PJ_SUCCESS; 82 } 83 84 PJ_DEF(pj_status_t) pjmedia_ vad_set_adaptive( pjmedia_vad *vad,85 unsigned frame_size)86 { 87 PJ_ASSERT_RETURN( vad && frame_size, PJ_EINVAL);88 89 vad->frame_size = frame_size;90 vad->mode = VAD_MODE_ADAPTIVE;91 vad->min_signal_cnt = 10;92 vad->min_silence_cnt = 64;93 vad->recalc_cnt = 250;94 vad->cur_threshold = 20;95 96 return PJ_SUCCESS; 97 } 98 99 PJ_DEF(pj_status_t) pjmedia_ vad_set_fixed( pjmedia_vad *vad,100 unsigned frame_size,101 unsigned threshold )102 { 103 PJ_ASSERT_RETURN( vad && frame_size, PJ_EINVAL);104 105 vad->mode = VAD_MODE_FIXED;106 vad->frame_size = frame_size;107 vad->cur_threshold = threshold;108 109 return PJ_SUCCESS; 110 } 111 112 PJ_DEF(pj_status_t) pjmedia_ vad_disable( pjmedia_vad *vad )113 { 114 PJ_ASSERT_RETURN( vad, PJ_EINVAL);115 116 vad->mode = VAD_MODE_NONE;117 118 return PJ_SUCCESS; 119 } 120 121 122 PJ_DEF(pj_int32_t) pjmedia_ vad_calc_avg_signal(const pj_int16_t samples[],123 pj_size_t count)77 sd->in_talk = PJ_FALSE; 78 pjmedia_silence_det_set_adaptive( sd, 160 ); 79 80 *p_sd = sd; 81 return PJ_SUCCESS; 82 } 83 84 PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 85 unsigned frame_size) 86 { 87 PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 88 89 sd->frame_size = frame_size; 90 sd->mode = VAD_MODE_ADAPTIVE; 91 sd->min_signal_cnt = 10; 92 sd->min_silence_cnt = 64; 93 sd->recalc_cnt = 250; 94 sd->cur_threshold = 20; 95 96 return PJ_SUCCESS; 97 } 98 99 PJ_DEF(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 100 unsigned frame_size, 101 unsigned threshold ) 102 { 103 PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 104 105 sd->mode = VAD_MODE_FIXED; 106 sd->frame_size = frame_size; 107 sd->cur_threshold = threshold; 108 109 return PJ_SUCCESS; 110 } 111 112 PJ_DEF(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd ) 113 { 114 PJ_ASSERT_RETURN(sd, PJ_EINVAL); 115 116 sd->mode = VAD_MODE_NONE; 117 118 return PJ_SUCCESS; 119 } 120 121 122 PJ_DEF(pj_int32_t) pjmedia_silence_det_calc_avg_signal(const pj_int16_t samples[], 123 pj_size_t count) 124 124 { 125 125 pj_uint32_t sum = 0; … … 141 141 } 142 142 143 PJ_DEF(pj_bool_t) pjmedia_ vad_detect_silence( pjmedia_vad *vad,144 const pj_int16_t samples[],145 pj_size_t count,146 pj_int32_t *p_level)143 PJ_DEF(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 144 const pj_int16_t samples[], 145 pj_size_t count, 146 pj_int32_t *p_level) 147 147 { 148 148 pj_uint32_t level; … … 150 150 151 151 /* Always return false if VAD is disabled */ 152 if ( vad->mode == VAD_MODE_NONE) {152 if (sd->mode == VAD_MODE_NONE) { 153 153 if (p_level) 154 154 *p_level = -1; … … 157 157 158 158 /* Calculate average signal level. */ 159 level = pjmedia_ vad_calc_avg_signal(samples, count);159 level = pjmedia_silence_det_calc_avg_signal(samples, count); 160 160 161 161 /* Report to caller, if required. */ … … 167 167 168 168 /* Do we have signal? */ 169 have_signal = level > vad->cur_threshold;169 have_signal = level > sd->cur_threshold; 170 170 171 171 /* We we're in transition between silence and signel, increment the … … 173 173 * frames. 174 174 */ 175 if ( vad->in_talk != have_signal) {175 if (sd->in_talk != have_signal) { 176 176 unsigned limit; 177 177 178 vad->cur_cnt++;179 180 limit = ( vad->in_talk ? vad->min_silence_cnt :181 vad->min_signal_cnt);182 183 if ( vad->cur_cnt > limit) {178 sd->cur_cnt++; 179 180 limit = (sd->in_talk ? sd->min_silence_cnt : 181 sd->min_signal_cnt); 182 183 if (sd->cur_cnt > limit) { 184 184 185 185 /* Swap mode */ 186 vad->in_talk = !vad->in_talk;186 sd->in_talk = !sd->in_talk; 187 187 188 188 /* Restart adaptive cur_threshold measurements */ 189 vad->weakest_signal = 0xFFFFFFFFUL;190 vad->loudest_silence = 0;191 vad->signal_cnt = 0;192 vad->silence_cnt = 0;189 sd->weakest_signal = 0xFFFFFFFFUL; 190 sd->loudest_silence = 0; 191 sd->signal_cnt = 0; 192 sd->silence_cnt = 0; 193 193 } 194 194 195 195 } else { 196 196 /* Reset frame count */ 197 vad->cur_cnt = 0;198 } 199 200 /* For fixed threshold vad, everything is done. */201 if ( vad->mode == VAD_MODE_FIXED) {202 return ! vad->in_talk;197 sd->cur_cnt = 0; 198 } 199 200 /* For fixed threshold sd, everything is done. */ 201 if (sd->mode == VAD_MODE_FIXED) { 202 return !sd->in_talk; 203 203 } 204 204 … … 206 206 /* Count the number of silent and signal frames and calculate min/max */ 207 207 if (have_signal) { 208 if (level < vad->weakest_signal)209 vad->weakest_signal = level;210 vad->signal_cnt++;208 if (level < sd->weakest_signal) 209 sd->weakest_signal = level; 210 sd->signal_cnt++; 211 211 } 212 212 else { 213 if (level > vad->loudest_silence)214 vad->loudest_silence = level;215 vad->silence_cnt++;213 if (level > sd->loudest_silence) 214 sd->loudest_silence = level; 215 sd->silence_cnt++; 216 216 } 217 217 … … 219 219 * silence/signal frames. 220 220 */ 221 if (( vad->signal_cnt + vad->silence_cnt) > vad->recalc_cnt) {221 if ((sd->signal_cnt + sd->silence_cnt) > sd->recalc_cnt) { 222 222 223 223 /* Adjust silence threshold by looking at the proportions of 224 224 * signal and silence frames. 225 225 */ 226 if ( vad->signal_cnt >= vad->recalc_cnt) {226 if (sd->signal_cnt >= sd->recalc_cnt) { 227 227 /* All frames where signal frames. 228 228 * Increase silence threshold. 229 229 */ 230 vad->cur_threshold += (vad->weakest_signal - vad->cur_threshold)/4;230 sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4; 231 231 PJ_LOG(6,(THIS_FILE, "Vad cur_threshold increased to %d", 232 vad->cur_threshold));233 } 234 else if ( vad->silence_cnt >= vad->recalc_cnt) {232 sd->cur_threshold)); 233 } 234 else if (sd->silence_cnt >= sd->recalc_cnt) { 235 235 /* All frames where silence frames. 236 236 * Decrease silence threshold. 237 237 */ 238 vad->cur_threshold = (vad->cur_threshold+vad->loudest_silence)/2+1;238 sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1; 239 239 PJ_LOG(6,(THIS_FILE, "Vad cur_threshold decreased to %d", 240 vad->cur_threshold));240 sd->cur_threshold)); 241 241 } 242 242 else { … … 244 244 245 245 /* Adjust according to signal/silence proportions. */ 246 if ( vad->signal_cnt > vad->silence_cnt * 2)247 vad->cur_threshold++;248 else if ( vad->silence_cnt > vad->signal_cnt* 2)249 vad->cur_threshold--;246 if (sd->signal_cnt > sd->silence_cnt * 2) 247 sd->cur_threshold++; 248 else if (sd->silence_cnt > sd->signal_cnt* 2) 249 sd->cur_threshold--; 250 250 else 251 251 updated = PJ_FALSE; … … 254 254 PJ_LOG(6,(THIS_FILE, 255 255 "Vad cur_threshold updated to %d", 256 vad->cur_threshold));256 sd->cur_threshold)); 257 257 } 258 258 } 259 259 260 260 /* Reset. */ 261 vad->weakest_signal = 0xFFFFFFFFUL;262 vad->loudest_silence = 0;263 vad->signal_cnt = 0;264 vad->silence_cnt = 0;265 } 266 267 return ! vad->in_talk;268 } 269 261 sd->weakest_signal = 0xFFFFFFFFUL; 262 sd->loudest_silence = 0; 263 sd->signal_cnt = 0; 264 sd->silence_cnt = 0; 265 } 266 267 return !sd->in_talk; 268 } 269
Note: See TracChangeset
for help on using the changeset viewer.