Changeset 904 for pjproject/trunk
- Timestamp:
- Jan 24, 2007 2:02:09 AM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/tonegen.h
r875 r904 99 99 100 100 101 /** 102 * Tone generator options. 103 */ 104 enum 105 { 106 /** 107 * Play the tones in loop, restarting playing the first tone after 108 * the last tone has been played. 109 */ 110 PJMEDIA_TONEGEN_LOOP = 1 111 }; 112 101 113 102 114 /** … … 112 124 * @param bits_per_sample Number of bits per sample. This version of PJMEDIA 113 125 * only supports 16bit per sample. 114 * @param options Option flags, must be zero for now. 126 * @param options Option flags. Application may specify 127 * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. 115 128 * @param p_port Pointer to receive the port instance. 116 129 * … … 128 141 129 142 /** 143 * Create an instance of tone generator with the specified parameters. 144 * When the tone generator is first created, it will be loaded with the 145 * default digit map. 146 * 147 * @param pool Pool to allocate memory for the port structure. 148 * @param name Optional name for the tone generator. 149 * @param clock_rate Sampling rate. 150 * @param channel_count Number of channels. Currently only mono and stereo 151 * are supported. 152 * @param samples_per_frame Number of samples per frame. 153 * @param bits_per_sample Number of bits per sample. This version of PJMEDIA 154 * only supports 16bit per sample. 155 * @param options Option flags. Application may specify 156 * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. 157 * @param p_port Pointer to receive the port instance. 158 * 159 * @return PJ_SUCCESS on success, or the appropriate 160 * error code. 161 */ 162 PJ_DECL(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool, 163 const pj_str_t *name, 164 unsigned clock_rate, 165 unsigned channel_count, 166 unsigned samples_per_frame, 167 unsigned bits_per_sample, 168 unsigned options, 169 pjmedia_port **p_port); 170 171 172 /** 130 173 * Check if the tone generator is still busy producing some tones. 131 174 * … … 157 200 * @param count The number of tones in the array. 158 201 * @param tones Array of tones to be played. 159 * @param options Playback options, must be zero for now. 202 * @param options Option flags. Application may specify 203 * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. 160 204 * 161 205 * @return PJ_SUCCESS on success, or PJ_ETOOMANY if … … 179 223 * @param count Number of digits in the array. 180 224 * @param digits Array of MF digits. 181 * @param options Playback options, must be zero for now. 225 * @param options Option flags. Application may specify 226 * PJMEDIA_TONEGEN_LOOP to play the tone in a loop. 182 227 * 183 228 * @return PJ_SUCCESS on success, or PJ_ETOOMANY if -
pjproject/trunk/pjmedia/src/pjmedia/tonegen.c
r747 r904 28 28 29 29 /* amplitude */ 30 #define AMP 1638330 #define AMP 8192 31 31 32 32 … … 234 234 pjmedia_port base; 235 235 236 /* options */ 237 unsigned options; 238 unsigned playback_options; 239 236 240 /* Digit map */ 237 241 pjmedia_tone_digit_map *digit_map; … … 281 285 * default digit map. 282 286 */ 287 PJ_DEF(pj_status_t) pjmedia_tonegen_create2(pj_pool_t *pool, 288 const pj_str_t *name, 289 unsigned clock_rate, 290 unsigned channel_count, 291 unsigned samples_per_frame, 292 unsigned bits_per_sample, 293 unsigned options, 294 pjmedia_port **p_port) 295 { 296 const pj_str_t STR_TONE_GEN = pj_str("tone-gen"); 297 struct tonegen *tonegen; 298 pj_status_t status; 299 300 PJ_ASSERT_RETURN(pool && clock_rate && channel_count && 301 samples_per_frame && bits_per_sample == 16 && 302 p_port != NULL, PJ_EINVAL); 303 304 /* Only support mono and stereo */ 305 PJ_ASSERT_RETURN(channel_count==1 || channel_count==2, PJ_EINVAL); 306 307 /* Create and initialize port */ 308 tonegen = pj_pool_zalloc(pool, sizeof(struct tonegen)); 309 if (name == NULL || name->slen == 0) name = &STR_TONE_GEN; 310 status = pjmedia_port_info_init(&tonegen->base.info, name, 311 SIGNATURE, clock_rate, channel_count, 312 bits_per_sample, samples_per_frame); 313 if (status != PJ_SUCCESS) 314 return status; 315 316 tonegen->options = options; 317 tonegen->base.get_frame = &tonegen_get_frame; 318 tonegen->digit_map = &digit_map; 319 320 /* Done */ 321 *p_port = &tonegen->base; 322 return PJ_SUCCESS; 323 } 324 325 283 326 PJ_DEF(pj_status_t) pjmedia_tonegen_create( pj_pool_t *pool, 284 327 unsigned clock_rate, … … 289 332 pjmedia_port **p_port) 290 333 { 291 const pj_str_t STR_TONE_GEN = pj_str("tone-gen"); 292 struct tonegen *tonegen; 293 pj_status_t status; 294 295 PJ_ASSERT_RETURN(pool && clock_rate && channel_count && 296 samples_per_frame && bits_per_sample == 16 && 297 options == 0 && p_port != NULL, PJ_EINVAL); 298 299 /* Only support mono and stereo */ 300 PJ_ASSERT_RETURN(channel_count==1 || channel_count==2, PJ_EINVAL); 301 302 /* Create and initialize port */ 303 tonegen = pj_pool_zalloc(pool, sizeof(struct tonegen)); 304 status = pjmedia_port_info_init(&tonegen->base.info, &STR_TONE_GEN, 305 SIGNATURE, clock_rate, channel_count, 306 bits_per_sample, samples_per_frame); 307 if (status != PJ_SUCCESS) 308 return status; 309 310 tonegen->base.get_frame = &tonegen_get_frame; 311 tonegen->digit_map = &digit_map; 312 313 /* Done */ 314 *p_port = &tonegen->base; 315 return PJ_SUCCESS; 334 return pjmedia_tonegen_create2(pool, NULL, clock_rate, channel_count, 335 samples_per_frame, bits_per_sample, 336 options, p_port); 316 337 } 317 338 … … 359 380 if (tonegen->cur_digit > tonegen->count) { 360 381 /* We have played all the digits */ 361 tonegen->count = 0; 362 frame->type = PJMEDIA_FRAME_TYPE_NONE; 363 return PJ_SUCCESS; 382 if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) 383 { 384 /* Reset back to the first tone */ 385 tonegen->cur_digit = 0; 386 tonegen->dig_samples = 0; 387 388 } else { 389 tonegen->count = 0; 390 frame->type = PJMEDIA_FRAME_TYPE_NONE; 391 return PJ_SUCCESS; 392 } 364 393 } 365 394 … … 377 406 * the digits 378 407 */ 379 tonegen->count = 0; 380 frame->type = PJMEDIA_FRAME_TYPE_NONE; 381 return PJ_SUCCESS; 408 if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) 409 { 410 /* Reset back to the first tone */ 411 tonegen->cur_digit = 0; 412 tonegen->dig_samples = 0; 413 414 } else { 415 tonegen->count = 0; 416 frame->type = PJMEDIA_FRAME_TYPE_NONE; 417 return PJ_SUCCESS; 418 } 382 419 } 383 420 … … 385 422 end = dst + port->info.samples_per_frame; 386 423 387 while (dst < end && tonegen->cur_digit < tonegen->count) {424 while (dst < end) { 388 425 const pjmedia_tone_desc *dig = &tonegen->digits[tonegen->cur_digit]; 389 426 unsigned required, cnt, on_samp, off_samp; … … 426 463 tonegen->cur_digit++; 427 464 tonegen->dig_samples = 0; 465 466 if (tonegen->cur_digit >= tonegen->count) { 467 /* All digits have been played */ 468 if ((tonegen->options & PJMEDIA_TONEGEN_LOOP) || 469 (tonegen->playback_options & PJMEDIA_TONEGEN_LOOP)) 470 { 471 tonegen->cur_digit = 0; 472 } else { 473 break; 474 } 475 } 428 476 } 429 477 } … … 435 483 frame->size = port->info.bytes_per_frame; 436 484 437 if (tonegen->cur_digit >= tonegen->count) 438 tonegen->count = 0; 485 if (tonegen->cur_digit >= tonegen->count) { 486 if ((tonegen->options|tonegen->playback_options)&PJMEDIA_TONEGEN_LOOP) 487 { 488 /* Reset back to the first tone */ 489 tonegen->cur_digit = 0; 490 tonegen->dig_samples = 0; 491 492 } else { 493 tonegen->count = 0; 494 } 495 } 439 496 440 497 return PJ_SUCCESS; … … 454 511 455 512 PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && 456 count && tones && options==0, PJ_EINVAL);513 count && tones, PJ_EINVAL); 457 514 458 515 /* Don't put more than available buffer */ … … 460 517 PJ_ETOOMANY); 461 518 519 /* Set playback options */ 520 tonegen->playback_options = options; 521 462 522 /* Copy digits */ 463 523 pj_memcpy(tonegen->digits + tonegen->count, … … 493 553 494 554 PJ_ASSERT_RETURN(port && port->info.signature == SIGNATURE && 495 count && digits && options==0, PJ_EINVAL);555 count && digits, PJ_EINVAL); 496 556 PJ_ASSERT_RETURN(count < PJMEDIA_TONEGEN_MAX_DIGITS, PJ_ETOOMANY); 497 557 -
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r903 r904 61 61 unsigned wav_count; 62 62 pj_str_t wav_files[32]; 63 unsigned tone_count; 64 pjmedia_tone_desc tones[32]; 65 pjsua_conf_port_id tone_slots[32]; 63 66 pjsua_player_id wav_id; 64 67 pjsua_conf_port_id wav_port; … … 159 162 puts (" --clock-rate=N Override sound device clock rate"); 160 163 puts (" --null-audio Use NULL audio device"); 161 puts (" --play-file=file Register WAV file in conference bridge"); 164 puts (" --play-file=file Register WAV file in conference bridge."); 165 puts (" This can be specified multiple times."); 166 puts (" --play-tone=F1,F2,ON,OFF Register tone to the conference bridge."); 167 puts (" f1,f2=frequency, on,off=on/off duration in msec."); 168 puts (" This can be specified multiple times."); 162 169 puts (" --auto-play Automatically play the file (to incoming calls only)"); 163 170 puts (" --auto-loop Automatically loop incoming RTP to outgoing RTP"); … … 310 317 OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP, 311 318 OPT_AUTO_CONF, OPT_CLOCK_RATE, 312 OPT_PLAY_FILE, OPT_ RTP_PORT, OPT_ADD_CODEC, OPT_ILBC_MODE,313 OPT_ REC_FILE, OPT_AUTO_REC,319 OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 320 OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC, 314 321 OPT_COMPLEXITY, OPT_QUALITY, OPT_PTIME, OPT_NO_VAD, 315 322 OPT_RX_DROP_PCT, OPT_TX_DROP_PCT, OPT_EC_TAIL, … … 358 365 { "auto-conf", 0, 0, OPT_AUTO_CONF}, 359 366 { "play-file", 1, 0, OPT_PLAY_FILE}, 367 { "play-tone", 1, 0, OPT_PLAY_TONE}, 360 368 { "rec-file", 1, 0, OPT_REC_FILE}, 361 369 { "rtp-port", 1, 0, OPT_RTP_PORT}, … … 682 690 break; 683 691 692 case OPT_PLAY_TONE: 693 { 694 int f1, f2, on, off; 695 int n; 696 697 n = sscanf(pj_optarg, "%d,%d,%d,%d", &f1, &f2, &on, &off); 698 if (n != 4) { 699 puts("Expecting f1,f2,on,off in --play-tone"); 700 return -1; 701 } 702 703 cfg->tones[cfg->tone_count].freq1 = (short)f1; 704 cfg->tones[cfg->tone_count].freq2 = (short)f2; 705 cfg->tones[cfg->tone_count].on_msec = (short)on; 706 cfg->tones[cfg->tone_count].off_msec = (short)off; 707 ++cfg->tone_count; 708 } 709 break; 710 684 711 case OPT_REC_FILE: 685 712 cfg->rec_file = pj_str(pj_optarg); … … 1135 1162 pj_ansi_sprintf(line, "--play-file %s\n", 1136 1163 config->wav_files[i].ptr); 1164 pj_strcat2(&cfg, line); 1165 } 1166 for (i=0; i<config->tone_count; ++i) { 1167 pj_ansi_sprintf(line, "--play-tone %d,%d,%d,%d\n", 1168 config->tones[i].freq1, config->tones[i].freq2, 1169 config->tones[i].on_msec, config->tones[i].off_msec); 1137 1170 pj_strcat2(&cfg, line); 1138 1171 } … … 2926 2959 } 2927 2960 2961 /* Optionally registers tone players */ 2962 for (i=0; i<app_config.tone_count; ++i) { 2963 pjmedia_port *tport; 2964 char name[80]; 2965 pj_str_t label; 2966 pj_status_t status; 2967 2968 pj_ansi_snprintf(name, sizeof(name), "tone-%d,%d", 2969 app_config.tones[i].freq1, 2970 app_config.tones[i].freq2); 2971 label = pj_str(name); 2972 status = pjmedia_tonegen_create2(app_config.pool, &label, 2973 8000, 1, 160, 16, 2974 PJMEDIA_TONEGEN_LOOP, &tport); 2975 if (status != PJ_SUCCESS) { 2976 pjsua_perror(THIS_FILE, "Unable to create tone generator", status); 2977 goto on_error; 2978 } 2979 2980 status = pjsua_conf_add_port(app_config.pool, tport, 2981 &app_config.tone_slots[i]); 2982 pj_assert(status == PJ_SUCCESS); 2983 2984 status = pjmedia_tonegen_play(tport, 1, &app_config.tones[i], 0); 2985 pj_assert(status == PJ_SUCCESS); 2986 } 2987 2928 2988 /* Optionally create recorder file, if any. */ 2929 2989 if (app_config.rec_file.slen) { … … 3057 3117 { 3058 3118 pj_status_t status; 3119 unsigned i; 3059 3120 3060 3121 #ifdef STEREO_DEMO … … 3064 3125 } 3065 3126 #endif 3127 3128 /* Close tone generators */ 3129 for (i=0; i<app_config.tone_count; ++i) { 3130 pjsua_conf_remove_port(app_config.tone_slots[i]); 3131 } 3066 3132 3067 3133 if (app_config.pool) {
Note: See TracChangeset
for help on using the changeset viewer.