diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-09-16 14:33:16 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-09-16 14:33:16 +0000 |
commit | b1c66224a0fab355eefa3bcbc9e791c13a31ce0f (patch) | |
tree | e30fcb1c7298ea37d7bd364f0dcd2ed6d398f2c3 /pjmedia/src | |
parent | 1a617d04a43d1bb2b32f7eca393f6ac3c65523e4 (diff) |
Ticket #619: added configuration to force floating point algorithm to be used in the tone generator, and added fade-in and fade out options
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2281 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src')
-rw-r--r-- | pjmedia/src/pjmedia/tonegen.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/pjmedia/src/pjmedia/tonegen.c b/pjmedia/src/pjmedia/tonegen.c index c217894e..562195d5 100644 --- a/pjmedia/src/pjmedia/tonegen.c +++ b/pjmedia/src/pjmedia/tonegen.c @@ -38,7 +38,8 @@ #endif -#if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 +#if (defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0) || \ + (defined(PJMEDIA_TONEGEN_FORCE_FLOAT) && PJMEDIA_TONEGEN_FORCE_FLOAT != 0) # include <math.h> # if defined(PJMEDIA_USE_HIGH_QUALITY_TONEGEN) && \ @@ -249,6 +250,8 @@ struct tonegen /* options */ unsigned options; unsigned playback_options; + unsigned fade_in_len; /* fade in for this # of samples */ + unsigned fade_out_len; /* fade out for this # of samples*/ /* lock */ pj_lock_t *lock; @@ -335,6 +338,9 @@ PJ_DEF(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool, tonegen->base.on_destroy = &tonegen_destroy; tonegen->digit_map = &digit_map; + tonegen->fade_in_len = PJMEDIA_TONEGEN_FADE_IN_TIME * clock_rate / 1000; + tonegen->fade_out_len = PJMEDIA_TONEGEN_FADE_OUT_TIME * clock_rate / 1000; + /* Lock */ if (options & PJMEDIA_TONEGEN_NO_LOCK) { status = pj_lock_create_null_mutex(pool, "tonegen", &tonegen->lock); @@ -533,10 +539,44 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port, cnt = required; generate_tone(&tonegen->state, port->info.channel_count, cnt, dst); + dst += cnt; tonegen->dig_samples += cnt; required -= cnt; + if (tonegen->dig_samples == cnt) { + /* Fade in */ + short *samp = (dst - cnt); + short *end; + + if (cnt > tonegen->fade_in_len) + cnt = tonegen->fade_in_len; + end = samp + cnt; + if (cnt) { + const unsigned step = 0xFFFF / cnt; + unsigned scale = 0; + + for (; samp < end; ++samp) { + (*samp) = (short)(((*samp) * scale) >> 16); + scale += step; + } + } + } else if (tonegen->dig_samples == on_samp) { + /* Fade out */ + if (cnt > tonegen->fade_out_len) + cnt = tonegen->fade_out_len; + if (cnt) { + short *samp = (dst - cnt); + const unsigned step = 0xFFFF / cnt; + unsigned scale = 0xFFFF - step; + + for (; samp < dst; ++samp) { + (*samp) = (short)(((*samp) * scale) >> 16); + scale -= step; + } + } + } + if (dst == end) break; } |