summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-06-05 06:17:38 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-06-05 06:17:38 +0000
commit5c55c6ae827ee835906e48e1657f64fa0a84f309 (patch)
tree107d94c8220e5cd42bea59c4e09ed49b23d1e8e9 /pjmedia
parent27220811ac7255bd957c179c9f1042443e786578 (diff)
Fixed bug in copying buffer and updated post process of buffer shrinking
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1982 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/src/pjmedia/delaybuf.c83
1 files changed, 52 insertions, 31 deletions
diff --git a/pjmedia/src/pjmedia/delaybuf.c b/pjmedia/src/pjmedia/delaybuf.c
index 37a50fe4..dca48476 100644
--- a/pjmedia/src/pjmedia/delaybuf.c
+++ b/pjmedia/src/pjmedia/delaybuf.c
@@ -216,24 +216,8 @@ static void shrink_buffer(pjmedia_delay_buf *b, unsigned erase_cnt)
b->buf_cnt -= erase_cnt;
- PJ_LOG(5,(b->obj_name,"Overflow, %d samples reduced, "
- "buf_cnt=%d", erase_cnt, b->buf_cnt));
- }
-
- /* Shrinking failed or erased count is less than requested,
- * delaybuf needs to drop eldest samples, this is bad since the voice
- * samples may not have smooth transition.
- */
- if (b->buf_cnt + b->samples_per_frame > b->max_cnt) {
- erase_cnt = b->buf_cnt + b->samples_per_frame - b->max_cnt;
-
- b->buf_cnt -= erase_cnt;
-
- /* Shift get_pos forward */
- b->get_pos = (b->get_pos + erase_cnt) % b->max_cnt;
-
- PJ_LOG(4,(b->obj_name,"Shrinking failed or insufficient, dropping"
- " %d eldest samples, buf_cnt=%d", erase_cnt, b->buf_cnt));
+ PJ_LOG(5,(b->obj_name,"%d samples reduced, buf_cnt=%d",
+ erase_cnt, b->buf_cnt));
}
}
@@ -286,8 +270,8 @@ static void update(pjmedia_delay_buf *b, enum OP op)
unsigned old_buf_cnt = b->buf_cnt;
shrink_buffer(b, erase_cnt);
- PJ_LOG(5,(b->obj_name,"Buffer size adjusted from %d to %d",
- old_buf_cnt, b->buf_cnt));
+ PJ_LOG(4,(b->obj_name,"Buffer size adjusted from %d to %d (eff_cnt=%d)",
+ old_buf_cnt, b->buf_cnt, b->eff_cnt));
}
}
@@ -311,11 +295,29 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
/* Overflow checking */
if (b->buf_cnt + b->samples_per_frame > b->max_cnt)
{
+ unsigned erase_cnt;
+
/* shrink one frame or just the diff? */
- //unsigned erase_cnt = b->samples_per_frame;
- unsigned erase_cnt = b->buf_cnt + b->samples_per_frame - b->max_cnt;
+ //erase_cnt = b->samples_per_frame;
+ erase_cnt = b->buf_cnt + b->samples_per_frame - b->max_cnt;
shrink_buffer(b, erase_cnt);
+
+ /* Check if shrinking failed or erased count is less than requested,
+ * delaybuf needs to drop eldest samples, this is bad since the voice
+ * samples get rough transition which may produce tick noise.
+ */
+ if (b->buf_cnt + b->samples_per_frame > b->max_cnt) {
+ erase_cnt = b->buf_cnt + b->samples_per_frame - b->max_cnt;
+
+ b->buf_cnt -= erase_cnt;
+
+ /* Shift get_pos forward */
+ b->get_pos = (b->get_pos + erase_cnt) % b->max_cnt;
+
+ PJ_LOG(4,(b->obj_name,"Shrinking failed or insufficient, dropping"
+ " %d eldest samples, buf_cnt=%d", erase_cnt, b->buf_cnt));
+ }
}
/* put the frame on put_pos */
@@ -354,7 +356,7 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
/* Starvation checking */
if (b->buf_cnt < b->samples_per_frame) {
- PJ_LOG(5,(b->obj_name,"Underflow, buf_cnt=%d, will generate 1 frame",
+ PJ_LOG(4,(b->obj_name,"Underflow, buf_cnt=%d, will generate 1 frame",
b->buf_cnt));
status = pjmedia_wsola_generate(b->wsola, frame);
@@ -384,18 +386,27 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
b->buf_cnt += b->samples_per_frame;
} else {
- /* Give all what delay buffer has, then pad zeroes */
+ /* Give all what delay buffer has, then pad with zeroes */
PJ_LOG(4,(b->obj_name,"Error generating frame, status=%d",
status));
- pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos], b->buf_cnt);
+ if (b->get_pos + b->buf_cnt <= b->max_cnt) {
+ pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos], b->buf_cnt);
+ } else {
+ int remainder = b->get_pos + b->buf_cnt - b->max_cnt;
+
+ pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos],
+ b->buf_cnt - remainder);
+ pjmedia_copy_samples(&frame[b->buf_cnt - remainder],
+ &b->frame_buf[0], remainder);
+ }
+
pjmedia_zero_samples(&frame[b->buf_cnt],
b->samples_per_frame - b->buf_cnt);
- b->get_pos += b->buf_cnt;
- b->buf_cnt = 0;
- /* Consistency checking */
- pj_assert(b->get_pos == b->put_pos);
+ /* Delay buf is empty */
+ b->get_pos = b->put_pos = 0;
+ b->buf_cnt = 0;
pj_lock_release(b->lock);
@@ -403,8 +414,18 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
}
}
- pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos],
- b->samples_per_frame);
+ if (b->get_pos + b->samples_per_frame <= b->max_cnt) {
+ pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos],
+ b->samples_per_frame);
+ } else {
+ int remainder = b->get_pos + b->samples_per_frame - b->max_cnt;
+
+ pjmedia_copy_samples(frame, &b->frame_buf[b->get_pos],
+ b->samples_per_frame - remainder);
+ pjmedia_copy_samples(&frame[b->samples_per_frame - remainder],
+ &b->frame_buf[0],
+ remainder);
+ }
b->get_pos = (b->get_pos + b->samples_per_frame) % b->max_cnt;
b->buf_cnt -= b->samples_per_frame;