summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2009-06-09 13:05:18 +0000
committerNanang Izzuddin <nanang@teluu.com>2009-06-09 13:05:18 +0000
commit54de99b9126223856df223ac0b27df66a5a5960a (patch)
tree1272ba93826f18d0938dae45850c19ba6aa0c5b8 /pjmedia
parent0a4ec5a59e51744adabf1307fe7e416f08dd4263 (diff)
Ticket #830: Fixed noise from EC by keeping the playing frames unmodified (pjmedia_delay_buf_put() may modify the input frames and there is a case that the modified frames are not aligned anymore).
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2757 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/src/pjmedia/echo_common.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/pjmedia/src/pjmedia/echo_common.c b/pjmedia/src/pjmedia/echo_common.c
index 920988d2..962e975b 100644
--- a/pjmedia/src/pjmedia/echo_common.c
+++ b/pjmedia/src/pjmedia/echo_common.c
@@ -52,6 +52,7 @@ struct pjmedia_echo_state
struct frame lat_free; /* Free frame list. */
pjmedia_delay_buf *delay_buf;
+ pj_int16_t *frm_buf;
};
@@ -152,6 +153,8 @@ PJ_DEF(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,
ec = PJ_POOL_ZALLOC_T(pool, struct pjmedia_echo_state);
ec->pool = pool;
ec->obj_name = pool->obj_name;
+ ec->samples_per_frame = samples_per_frame;
+ ec->frm_buf = (pj_int16_t*)pj_pool_alloc(pool, samples_per_frame<<1);
pj_list_init(&ec->lat_buf);
pj_list_init(&ec->lat_free);
@@ -274,6 +277,23 @@ PJ_DEF(pj_status_t) pjmedia_echo_reset(pjmedia_echo_state *echo )
PJ_DEF(pj_status_t) pjmedia_echo_playback( pjmedia_echo_state *echo,
pj_int16_t *play_frm )
{
+ /* Playing frame should be stored, as it will be used by echo_capture()
+ * as reference frame, delay buffer is used for storing the playing frames
+ * as in case there was clock drift between mic & speaker.
+ *
+ * Ticket #830:
+ * Note that pjmedia_delay_buf_put() may modify the input frame and those
+ * modified frames may not be smooth, i.e: if there were two or more
+ * consecutive pjmedia_delay_buf_get() before next pjmedia_delay_buf_put(),
+ * so we'll just feed the delay buffer with the copy of playing frame,
+ * instead of the original playing frame. However this will cause the EC
+ * uses slight 'different' frames (for reference) than actually played
+ * by the speaker.
+ */
+ pjmedia_copy_samples(echo->frm_buf, play_frm,
+ echo->samples_per_frame);
+ pjmedia_delay_buf_put(echo->delay_buf, echo->frm_buf);
+
if (!echo->lat_ready) {
/* We've not built enough latency in the buffer, so put this frame
* in the latency buffer list.
@@ -283,21 +303,16 @@ PJ_DEF(pj_status_t) pjmedia_echo_playback( pjmedia_echo_state *echo,
if (pj_list_empty(&echo->lat_free)) {
echo->lat_ready = PJ_TRUE;
PJ_LOG(5,(echo->obj_name, "Latency bufferring complete"));
- pjmedia_delay_buf_put(echo->delay_buf, play_frm);
return PJ_SUCCESS;
}
frm = echo->lat_free.prev;
pj_list_erase(frm);
- pjmedia_copy_samples(frm->buf, play_frm, echo->samples_per_frame);
+ /* Move one frame from delay buffer to the latency buffer. */
+ pjmedia_delay_buf_get(echo->delay_buf, echo->frm_buf);
+ pjmedia_copy_samples(frm->buf, echo->frm_buf, echo->samples_per_frame);
pj_list_push_back(&echo->lat_buf, frm);
-
- } else {
- /* Latency buffer is ready (full), so we put this frame in the
- * delay buffer.
- */
- pjmedia_delay_buf_put(echo->delay_buf, play_frm);
}
return PJ_SUCCESS;