summaryrefslogtreecommitdiff
path: root/pjmedia/src
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2011-05-15 12:54:28 +0000
committerLiong Sauw Ming <ming@teluu.com>2011-05-15 12:54:28 +0000
commit9d61f9ded11c24cef9c18962c65fda728e871568 (patch)
tree1313ee0a832c5830c956b8168e107610750d9417 /pjmedia/src
parent662b61f41a7da47a976ff29fd33ebfa860be05b7 (diff)
Fixed #1257: Option for using simple FIFO delay buffer in echo canceller.
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@3567 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r--pjmedia/src/pjmedia/delaybuf.c97
-rw-r--r--pjmedia/src/pjmedia/echo_common.c5
2 files changed, 60 insertions, 42 deletions
diff --git a/pjmedia/src/pjmedia/delaybuf.c b/pjmedia/src/pjmedia/delaybuf.c
index 39f0e618..82618275 100644
--- a/pjmedia/src/pjmedia/delaybuf.c
+++ b/pjmedia/src/pjmedia/delaybuf.c
@@ -99,9 +99,6 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_create( pj_pool_t *pool,
PJ_ASSERT_RETURN(pool && samples_per_frame && clock_rate && channel_count &&
p_b, PJ_EINVAL);
- PJ_ASSERT_RETURN(options==0, PJ_EINVAL);
-
- PJ_UNUSED_ARG(options);
if (!name) {
name = "delaybuf";
@@ -126,11 +123,16 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_create( pj_pool_t *pool,
if (status != PJ_SUCCESS)
return status;
- /* Create WSOLA */
- status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,
- PJMEDIA_WSOLA_NO_FADING, &b->wsola);
- if (status != PJ_SUCCESS)
- return status;
+ if (!(options & PJMEDIA_DELAY_BUF_SIMPLE_FIFO)) {
+ /* Create WSOLA */
+ status = pjmedia_wsola_create(pool, clock_rate, samples_per_frame, 1,
+ PJMEDIA_WSOLA_NO_FADING, &b->wsola);
+ if (status != PJ_SUCCESS)
+ return status;
+ PJ_LOG(5, (b->obj_name, "Using delay buffer with WSOLA."));
+ } else {
+ PJ_LOG(5, (b->obj_name, "Using simple FIFO delay buffer."));
+ }
/* Finally, create mutex */
status = pj_lock_create_recursive_mutex(pool, b->obj_name,
@@ -147,15 +149,17 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_create( pj_pool_t *pool,
PJ_DEF(pj_status_t) pjmedia_delay_buf_destroy(pjmedia_delay_buf *b)
{
- pj_status_t status;
+ pj_status_t status = PJ_SUCCESS;
PJ_ASSERT_RETURN(b, PJ_EINVAL);
pj_lock_acquire(b->lock);
- status = pjmedia_wsola_destroy(b->wsola);
- if (status == PJ_SUCCESS)
- b->wsola = NULL;
+ if (b->wsola) {
+ status = pjmedia_wsola_destroy(b->wsola);
+ if (status == PJ_SUCCESS)
+ b->wsola = NULL;
+ }
pj_lock_release(b->lock);
@@ -264,12 +268,14 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
pj_lock_acquire(b->lock);
- update(b, OP_PUT);
+ if (b->wsola) {
+ update(b, OP_PUT);
- status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE);
- if (status != PJ_SUCCESS) {
- pj_lock_release(b->lock);
- return status;
+ status = pjmedia_wsola_save(b->wsola, frame, PJ_FALSE);
+ if (status != PJ_SUCCESS) {
+ pj_lock_release(b->lock);
+ return status;
+ }
}
/* Overflow checking */
@@ -277,13 +283,15 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
b->max_cnt)
{
unsigned erase_cnt;
-
- /* shrink one frame or just the diff? */
- //erase_cnt = b->samples_per_frame;
- erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +
- b->samples_per_frame - b->max_cnt;
- shrink_buffer(b, erase_cnt);
+ if (b->wsola) {
+ /* shrink one frame or just the diff? */
+ //erase_cnt = b->samples_per_frame;
+ erase_cnt = pjmedia_circ_buf_get_len(b->circ_buf) +
+ 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
@@ -297,9 +305,9 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
pjmedia_circ_buf_adv_read_ptr(b->circ_buf, erase_cnt);
- PJ_LOG(4,(b->obj_name,"Shrinking failed or insufficient, dropping"
- " %d eldest samples, buf_cnt=%d", erase_cnt,
- pjmedia_circ_buf_get_len(b->circ_buf)));
+ PJ_LOG(4,(b->obj_name,"%sDropping %d eldest samples, buf_cnt=%d",
+ (b->wsola? "Shrinking failed or insufficient. ": ""),
+ erase_cnt, pjmedia_circ_buf_get_len(b->circ_buf)));
}
}
@@ -312,13 +320,14 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_put(pjmedia_delay_buf *b,
PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
pj_int16_t frame[])
{
- pj_status_t status;
+ pj_status_t status = PJ_SUCCESS;
PJ_ASSERT_RETURN(b && frame, PJ_EINVAL);
pj_lock_acquire(b->lock);
- update(b, OP_GET);
+ if (b->wsola)
+ update(b, OP_GET);
/* Starvation checking */
if (pjmedia_circ_buf_get_len(b->circ_buf) < b->samples_per_frame) {
@@ -326,24 +335,29 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_get( pjmedia_delay_buf *b,
PJ_LOG(4,(b->obj_name,"Underflow, buf_cnt=%d, will generate 1 frame",
pjmedia_circ_buf_get_len(b->circ_buf)));
- status = pjmedia_wsola_generate(b->wsola, frame);
+ if (b->wsola) {
+ status = pjmedia_wsola_generate(b->wsola, frame);
- if (status == PJ_SUCCESS) {
- TRACE__((b->obj_name,"Successfully generate 1 frame"));
- if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) {
- pj_lock_release(b->lock);
- return PJ_SUCCESS;
- }
+ if (status == PJ_SUCCESS) {
+ TRACE__((b->obj_name,"Successfully generate 1 frame"));
+ if (pjmedia_circ_buf_get_len(b->circ_buf) == 0) {
+ pj_lock_release(b->lock);
+ return PJ_SUCCESS;
+ }
- /* Put generated frame into buffer */
- pjmedia_circ_buf_write(b->circ_buf, frame, b->samples_per_frame);
+ /* Put generated frame into buffer */
+ pjmedia_circ_buf_write(b->circ_buf, frame,
+ b->samples_per_frame);
+ }
+ }
- } else {
+ if (!b->wsola || status != PJ_SUCCESS) {
unsigned buf_len = pjmedia_circ_buf_get_len(b->circ_buf);
/* Give all what delay buffer has, then pad with zeroes */
- PJ_LOG(4,(b->obj_name,"Error generating frame, status=%d",
- status));
+ if (b->wsola)
+ PJ_LOG(4,(b->obj_name,"Error generating frame, status=%d",
+ status));
pjmedia_circ_buf_read(b->circ_buf, frame, buf_len);
pjmedia_zero_samples(&frame[buf_len],
@@ -378,7 +392,8 @@ PJ_DEF(pj_status_t) pjmedia_delay_buf_reset(pjmedia_delay_buf *b)
pjmedia_circ_buf_reset(b->circ_buf);
/* Reset WSOLA */
- pjmedia_wsola_reset(b->wsola, 0);
+ if (b->wsola)
+ pjmedia_wsola_reset(b->wsola, 0);
pj_lock_release(b->lock);
diff --git a/pjmedia/src/pjmedia/echo_common.c b/pjmedia/src/pjmedia/echo_common.c
index 1cb2e311..532c37be 100644
--- a/pjmedia/src/pjmedia/echo_common.c
+++ b/pjmedia/src/pjmedia/echo_common.c
@@ -144,6 +144,7 @@ PJ_DEF(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,
pjmedia_echo_state **p_echo )
{
unsigned ptime, lat_cnt;
+ unsigned delay_buf_opt = 0;
pjmedia_echo_state *ec;
pj_status_t status;
@@ -211,10 +212,12 @@ PJ_DEF(pj_status_t) pjmedia_echo_create2(pj_pool_t *pool,
}
/* Create delay buffer to compensate drifts */
+ if (options & PJMEDIA_ECHO_USE_SIMPLE_FIFO)
+ delay_buf_opt |= PJMEDIA_DELAY_BUF_SIMPLE_FIFO;
status = pjmedia_delay_buf_create(ec->pool, ec->obj_name, clock_rate,
samples_per_frame, channel_count,
(PJMEDIA_SOUND_BUFFER_COUNT+1) * ptime,
- 0, &ec->delay_buf);
+ delay_buf_opt, &ec->delay_buf);
if (status != PJ_SUCCESS) {
pj_pool_release(pool);
return status;