- Timestamp:
- Oct 21, 2013 3:11:14 AM (11 years ago)
- Location:
- pjproject/trunk/pjmedia/src/pjmedia
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/echo_common.c
r3841 r4622 75 75 unsigned options, 76 76 void *reserved ); 77 pj_status_t (*ec_playback)(void *state, 78 pj_int16_t *play_frm ); 79 pj_status_t (*ec_capture)(void *state, 80 pj_int16_t *rec_frm, 81 unsigned options ); 77 82 }; 78 83 … … 99 104 &speex_aec_destroy, 100 105 &speex_aec_reset, 101 &speex_aec_cancel_echo 106 &speex_aec_cancel_echo, 107 &speex_aec_playback, 108 &speex_aec_capture 102 109 }; 103 110 #endif … … 183 190 } 184 191 192 /* Completeness check for EC operation playback and capture, they must 193 * be implemented both or none. 194 */ 195 pj_assert(!ec->op->ec_capture == !ec->op->ec_playback); 196 185 197 PJ_LOG(5,(ec->obj_name, "Creating %s", ec->op->name)); 186 198 … … 194 206 } 195 207 196 /* Create latency buffers */ 197 ptime = samples_per_frame * 1000 / clock_rate; 198 if (latency_ms > ptime) { 199 /* Normalize latency with delaybuf/WSOLA latency */ 200 latency_ms -= PJ_MIN(ptime, PJMEDIA_WSOLA_DELAY_MSEC); 201 } 202 if (latency_ms < ptime) { 203 /* Give at least one frame delay to simplify programming */ 204 latency_ms = ptime; 205 } 206 lat_cnt = latency_ms / ptime; 207 while (lat_cnt--) { 208 struct frame *frm; 209 210 frm = (struct frame*) pj_pool_alloc(pool, (samples_per_frame<<1) + 211 sizeof(struct frame)); 212 pj_list_push_back(&ec->lat_free, frm); 213 } 214 215 /* Create delay buffer to compensate drifts */ 216 if (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO) 217 delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO; 218 status = pjmedia_delay_buf_create(ec->pool, ec->obj_name, clock_rate, 219 samples_per_frame, channel_count, 220 (PJMEDIA_SOUND_BUFFER_COUNT+1) * ptime, 221 delay_buf_opt, &ec->delay_buf); 222 if (status != PJ_SUCCESS) { 223 pj_pool_release(pool); 224 return status; 208 /* If EC algo does not have playback and capture callbakcs, 209 * create latency buffer and delay buffer to handle drift. 210 */ 211 if (ec->op->ec_playback && ec->op->ec_capture) { 212 latency_ms = 0; 213 } else { 214 /* Create latency buffers */ 215 ptime = samples_per_frame * 1000 / clock_rate; 216 if (latency_ms > ptime) { 217 /* Normalize latency with delaybuf/WSOLA latency */ 218 latency_ms -= PJ_MIN(ptime, PJMEDIA_WSOLA_DELAY_MSEC); 219 } 220 if (latency_ms < ptime) { 221 /* Give at least one frame delay to simplify programming */ 222 latency_ms = ptime; 223 } 224 lat_cnt = latency_ms / ptime; 225 while (lat_cnt--) { 226 struct frame *frm; 227 228 frm = (struct frame*) pj_pool_alloc(pool, (samples_per_frame<<1) + 229 sizeof(struct frame)); 230 pj_list_push_back(&ec->lat_free, frm); 231 } 232 233 /* Create delay buffer to compensate drifts */ 234 if (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO) 235 delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO; 236 status = pjmedia_delay_buf_create(ec->pool, ec->obj_name, clock_rate, 237 samples_per_frame, channel_count, 238 (PJMEDIA_SOUND_BUFFER_COUNT+1) * ptime, 239 delay_buf_opt, &ec->delay_buf); 240 if (status != PJ_SUCCESS) { 241 pj_pool_release(pool); 242 return status; 243 } 225 244 } 226 245 … … 268 287 } 269 288 echo->lat_ready = PJ_FALSE; 270 pjmedia_delay_buf_reset(echo->delay_buf); 289 if (echo->delay_buf) 290 pjmedia_delay_buf_reset(echo->delay_buf); 271 291 echo->op->ec_reset(echo->state); 272 292 return PJ_SUCCESS; … … 280 300 pj_int16_t *play_frm ) 281 301 { 302 /* If EC algo has playback handler, just pass the frame. */ 303 if (echo->op->ec_playback) { 304 return (*echo->op->ec_playback)(echo->state, play_frm); 305 } 306 282 307 /* Playing frame should be stored, as it will be used by echo_capture() 283 308 * as reference frame, delay buffer is used for storing the playing frames … … 333 358 pj_status_t status, rc; 334 359 360 /* If EC algo has capture handler, just pass the frame. */ 361 if (echo->op->ec_capture) { 362 return (*echo->op->ec_capture)(echo->state, rec_frm, options); 363 } 364 335 365 if (!echo->lat_ready) { 336 366 /* Prefetching to fill in the desired latency */ -
pjproject/trunk/pjmedia/src/pjmedia/echo_internal.h
r3553 r4622 57 57 unsigned options, 58 58 void *reserved ); 59 PJ_DECL(pj_status_t) speex_aec_playback(void *state, 60 pj_int16_t *play_frm ); 61 PJ_DECL(pj_status_t) speex_aec_capture(void *state, 62 pj_int16_t *rec_frm, 63 unsigned options ); 59 64 60 65 PJ_DECL(pj_status_t) ipp_aec_create(pj_pool_t *pool, -
pjproject/trunk/pjmedia/src/pjmedia/echo_speex.c
r3664 r4622 110 110 #endif 111 111 112 /* Enable AGC */ 113 { 114 spx_int32_t enabled = 1; 115 speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_AGC, 116 &enabled); 117 } 118 112 119 /* Control echo cancellation in the preprocessor */ 113 120 speex_preprocess_ctl(echo->preprocess, SPEEX_PREPROCESS_SET_ECHO_STATE, … … 190 197 } 191 198 199 /* 200 * Let AEC know that a frame was queued to be played. 201 */ 202 PJ_DEF(pj_status_t) speex_aec_playback( void *state, 203 pj_int16_t *play_frm ) 204 { 205 speex_ec *echo = (speex_ec*) state; 206 207 /* Sanity checks */ 208 PJ_ASSERT_RETURN(echo && play_frm, PJ_EINVAL); 209 210 speex_echo_playback(echo->state, (spx_int16_t*)play_frm); 211 212 return PJ_SUCCESS; 213 214 } 215 216 /* 217 * Perform echo cancellation to captured frame. 218 */ 219 PJ_DEF(pj_status_t) speex_aec_capture( void *state, 220 pj_int16_t *rec_frm, 221 unsigned options ) 222 { 223 speex_ec *echo = (speex_ec*) state; 224 225 /* Sanity checks */ 226 PJ_ASSERT_RETURN(echo && rec_frm, PJ_EINVAL); 227 228 PJ_UNUSED_ARG(options); 229 230 /* Cancel echo */ 231 pjmedia_copy_samples(echo->tmp_frame, rec_frm, echo->samples_per_frame); 232 speex_echo_capture(echo->state, 233 (spx_int16_t*)echo->tmp_frame, 234 (spx_int16_t*)rec_frm); 235 236 /* Apply preprocessing */ 237 speex_preprocess_run(echo->preprocess, (spx_int16_t*)rec_frm); 238 239 return PJ_SUCCESS; 240 } 241 242 192 243 #endif
Note: See TracChangeset
for help on using the changeset viewer.