diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-01-24 02:02:09 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-01-24 02:02:09 +0000 |
commit | b7680744381c03eeaf56d600c30ba95c062cec1b (patch) | |
tree | 3ee9d55c6ddd44483c5b69c399da7d9e6c0f293f /pjmedia | |
parent | f362291d6e707ba5400937d89350f98827ff6e85 (diff) |
Implement ticket #62: option to play tones continuously, and added --play-tone option in pjsua
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@904 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r-- | pjmedia/include/pjmedia/tonegen.h | 51 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/tonegen.c | 90 |
2 files changed, 123 insertions, 18 deletions
diff --git a/pjmedia/include/pjmedia/tonegen.h b/pjmedia/include/pjmedia/tonegen.h index 21a4f063..c167e11d 100644 --- a/pjmedia/include/pjmedia/tonegen.h +++ b/pjmedia/include/pjmedia/tonegen.h @@ -98,6 +98,18 @@ typedef struct pjmedia_tone_digit_map } pjmedia_tone_digit_map; +/** + * Tone generator options. + */ +enum +{ + /** + * Play the tones in loop, restarting playing the first tone after + * the last tone has been played. + */ + PJMEDIA_TONEGEN_LOOP = 1 +}; + /** * Create an instance of tone generator with the specified parameters. @@ -111,7 +123,8 @@ typedef struct pjmedia_tone_digit_map * @param samples_per_frame Number of samples per frame. * @param bits_per_sample Number of bits per sample. This version of PJMEDIA * only supports 16bit per sample. - * @param options Option flags, must be zero for now. + * @param options Option flags. Application may specify + * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. * @param p_port Pointer to receive the port instance. * * @return PJ_SUCCESS on success, or the appropriate @@ -127,6 +140,36 @@ PJ_DECL(pj_status_t) pjmedia_tonegen_create(pj_pool_t *pool, /** + * Create an instance of tone generator with the specified parameters. + * When the tone generator is first created, it will be loaded with the + * default digit map. + * + * @param pool Pool to allocate memory for the port structure. + * @param name Optional name for the tone generator. + * @param clock_rate Sampling rate. + * @param channel_count Number of channels. Currently only mono and stereo + * are supported. + * @param samples_per_frame Number of samples per frame. + * @param bits_per_sample Number of bits per sample. This version of PJMEDIA + * only supports 16bit per sample. + * @param options Option flags. Application may specify + * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. + * @param p_port Pointer to receive the port instance. + * + * @return PJ_SUCCESS on success, or the appropriate + * error code. + */ +PJ_DECL(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool, + const pj_str_t *name, + unsigned clock_rate, + unsigned channel_count, + unsigned samples_per_frame, + unsigned bits_per_sample, + unsigned options, + pjmedia_port **p_port); + + +/** * Check if the tone generator is still busy producing some tones. * * @param tonegen The tone generator instance. @@ -156,7 +199,8 @@ PJ_DECL(pj_status_t) pjmedia_tonegen_stop(pjmedia_port *tonegen); * @param tonegen The tone generator instance. * @param count The number of tones in the array. * @param tones Array of tones to be played. - * @param options Playback options, must be zero for now. + * @param options Option flags. Application may specify + * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. * * @return PJ_SUCCESS on success, or PJ_ETOOMANY if * there are too many digits in the queue. @@ -178,7 +222,8 @@ PJ_DECL(pj_status_t) pjmedia_tonegen_play(pjmedia_port *tonegen, * @param tonegen The tone generator instance. * @param count Number of digits in the array. * @param digits Array of MF digits. - * @param options Playback options, must be zero for now. + * @param options Option flags. Application may specify + * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. * * @return PJ_SUCCESS on success, or PJ_ETOOMANY if * there are too many digits in the queue, or diff --git a/pjmedia/src/pjmedia/tonegen.c b/pjmedia/src/pjmedia/tonegen.c index 2e62ce88..e913e6aa 100644 --- a/pjmedia/src/pjmedia/tonegen.c +++ b/pjmedia/src/pjmedia/tonegen.c @@ -27,7 +27,7 @@ #define DATA double /* amplitude */ -#define AMP 16383 +#define AMP 8192 #ifndef M_PI @@ -233,6 +233,10 @@ struct tonegen { pjmedia_port base; + /* options */ + unsigned options; + unsigned playback_options; + /* Digit map */ pjmedia_tone_digit_map *digit_map; @@ -280,7 +284,8 @@ static pj_status_t tonegen_get_frame(pjmedia_port *this_port, * When the tone generator is first created, it will be loaded with the * default digit map. */ -PJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool, +PJ_DEF(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool, + const pj_str_t *name, unsigned clock_rate, unsigned channel_count, unsigned samples_per_frame, @@ -294,19 +299,21 @@ PJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool, PJ_ASSERT_RETURN(pool && clock_rate && channel_count && samples_per_frame && bits_per_sample == 16 && - options == 0 && p_port != NULL, PJ_EINVAL); + p_port != NULL, PJ_EINVAL); /* Only support mono and stereo */ PJ_ASSERT_RETURN(channel_count==1 || channel_count==2, PJ_EINVAL); /* Create and initialize port */ tonegen = pj_pool_zalloc(pool, sizeof(struct tonegen)); - status = pjmedia_port_info_init(&tonegen->base.info, &STR_TONE_GEN, + if (name == NULL || name->slen == 0) name = &STR_TONE_GEN; + status = pjmedia_port_info_init(&tonegen->base.info, name, SIGNATURE, clock_rate, channel_count, bits_per_sample, samples_per_frame); if (status != PJ_SUCCESS) return status; + tonegen->options = options; tonegen->base.get_frame = &tonegen_get_frame; tonegen->digit_map = &digit_map; @@ -316,6 +323,20 @@ PJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool, } +PJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool, + unsigned clock_rate, + unsigned channel_count, + unsigned samples_per_frame, + unsigned bits_per_sample, + unsigned options, + pjmedia_port **p_port) +{ + return pjmedia_tonegen_create2(pool, NULL, clock_rate, channel_count, + samples_per_frame, bits_per_sample, + options, p_port); +} + + /* * Check if the tone generator is still busy producing some tones. */ @@ -358,9 +379,17 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port, if (tonegen->cur_digit > tonegen->count) { /* We have played all the digits */ - tonegen->count = 0; - frame->type = PJMEDIA_FRAME_TYPE_NONE; - return PJ_SUCCESS; + if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) + { + /* Reset back to the first tone */ + tonegen->cur_digit = 0; + tonegen->dig_samples = 0; + + } else { + tonegen->count = 0; + frame->type = PJMEDIA_FRAME_TYPE_NONE; + return PJ_SUCCESS; + } } if (tonegen->dig_samples>=(tonegen->digits[tonegen->cur_digit].on_msec+ @@ -376,15 +405,23 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port, /* After we're finished with the last digit, we have played all * the digits */ - tonegen->count = 0; - frame->type = PJMEDIA_FRAME_TYPE_NONE; - return PJ_SUCCESS; + if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) + { + /* Reset back to the first tone */ + tonegen->cur_digit = 0; + tonegen->dig_samples = 0; + + } else { + tonegen->count = 0; + frame->type = PJMEDIA_FRAME_TYPE_NONE; + return PJ_SUCCESS; + } } dst = frame->buf; end = dst + port->info.samples_per_frame; - while (dst < end && tonegen->cur_digit < tonegen->count) { + while (dst < end) { const pjmedia_tone_desc *dig = &tonegen->digits[tonegen->cur_digit]; unsigned required, cnt, on_samp, off_samp; @@ -425,6 +462,17 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port, if (tonegen->dig_samples == on_samp + off_samp) { tonegen->cur_digit++; tonegen->dig_samples = 0; + + if (tonegen->cur_digit >= tonegen->count) { + /* All digits have been played */ + if ((tonegen->options & PJMEDIA_TONEGEN_LOOP) || + (tonegen->playback_options & PJMEDIA_TONEGEN_LOOP)) + { + tonegen->cur_digit = 0; + } else { + break; + } + } } } @@ -434,8 +482,17 @@ static pj_status_t tonegen_get_frame(pjmedia_port *port, frame->type = PJMEDIA_FRAME_TYPE_AUDIO; frame->size = port->info.bytes_per_frame; - if (tonegen->cur_digit >= tonegen->count) - tonegen->count = 0; + if (tonegen->cur_digit >= tonegen->count) { + if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) + { + /* Reset back to the first tone */ + tonegen->cur_digit = 0; + tonegen->dig_samples = 0; + + } else { + tonegen->count = 0; + } + } return PJ_SUCCESS; } @@ -453,12 +510,15 @@ PJ_DEF(pj_status_t) pjmedia_tonegen_play( pjmedia_port *port, unsigned i; PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && - count && tones && options==0, PJ_EINVAL); + count && tones, PJ_EINVAL); /* Don't put more than available buffer */ PJ_ASSERT_RETURN(count+tonegen->count <= PJMEDIA_TONEGEN_MAX_DIGITS, PJ_ETOOMANY); + /* Set playback options */ + tonegen->playback_options = options; + /* Copy digits */ pj_memcpy(tonegen->digits + tonegen->count, tones, count * sizeof(pjmedia_tone_desc)); @@ -492,7 +552,7 @@ PJ_DEF(pj_status_t) pjmedia_tonegen_play_digits( pjmedia_port *port, unsigned i; PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && - count && digits && options==0, PJ_EINVAL); + count && digits, PJ_EINVAL); PJ_ASSERT_RETURN(count < PJMEDIA_TONEGEN_MAX_DIGITS, PJ_ETOOMANY); for (i=0; i<count; ++i) { |