Changeset 229 for pjproject/trunk
- Timestamp:
- Feb 25, 2006 9:15:49 PM (19 years ago)
- Location:
- pjproject/trunk/pjmedia
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/build/pjmedia.dsp
r228 r229 66 66 # PROP Target_Dir "" 67 67 # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c 68 # ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../src/pjmedia/portaudio" /D "_DEBUG" /D "PA_NO_ASIO" /D " WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c68 # ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../src/pjmedia/portaudio" /D "_DEBUG" /D "PA_NO_ASIO" /D "PA_NO_WMME" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /GZ /c 69 69 # SUBTRACT CPP /YX 70 70 # ADD BASE RSC /l 0x409 /d "_DEBUG" -
pjproject/trunk/pjmedia/include/pjmedia/silencedet.h
r228 r229 86 86 87 87 /** 88 * Calculate average signal level for the given samples. 89 * 90 * @param samples Pointer to 16-bit PCM samples. 91 * @param count Number of samples in the input. 92 * 93 * @return The average signal level, which simply is total level 94 * divided by number of samples. 95 */ 96 PJ_DECL(pj_int32_t) pjmedia_silence_det_calc_avg_signal( const pj_int16_t samples[], 97 pj_size_t count ); 98 99 100 /** 101 * Perform voice activity detection on the given input samples. 88 * Perform voice activity detection on the given input samples. This 89 * function uses #pjmedia_calc_avg_signal() and #pjmedia_silence_det_apply() 90 * for its calculation. 102 91 * 103 92 * @param sd The silence detector instance. … … 109 98 * @return PJ_SUCCESS on success. 110 99 */ 111 PJ_DECL(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 112 const pj_int16_t samples[], 113 pj_size_t count, 114 pj_int32_t *p_level); 100 PJ_DECL(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd, 101 const pj_int16_t samples[], 102 pj_size_t count, 103 pj_int32_t *p_level); 104 105 106 /** 107 * Calculate average signal level for the given samples. 108 * 109 * @param samples Pointer to 16-bit PCM samples. 110 * @param count Number of samples in the input. 111 * 112 * @return The average signal level, which simply is total level 113 * divided by number of samples. 114 */ 115 PJ_DECL(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[], 116 pj_size_t count ); 117 118 119 120 /** 121 * Perform voice activity detection, given the specified average signal 122 * level. 123 * 124 * @param sd The silence detector instance. 125 * @param level Signal level. 126 * 127 * @return PJ_SUCCESS on success. 128 */ 129 PJ_DECL(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd, 130 pj_uint32_t level); 115 131 116 132 -
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r228 r229 92 92 pj_snd_stream *snd_rec; /**< Sound recorder stream. */ 93 93 pj_snd_stream *snd_player; /**< Sound player stream. */ 94 pj_mutex_t *mutex; /**< Conference mutex. */ 94 95 struct conf_port **ports; /**< Array of ports. */ 95 96 pj_uint16_t *uns_buf; /**< Buf for unsigned conversion */ … … 100 101 }; 101 102 103 104 /* Extern */ 105 unsigned char linear2ulaw(int pcm_val); 102 106 103 107 /* Prototypes */ … … 261 265 conf->uns_buf = pj_pool_zalloc(pool, samples_per_frame * 262 266 sizeof(conf->uns_buf[0])); 267 268 /* Create mutex. */ 269 status = pj_mutex_create_simple(pool, "conf", &conf->mutex); 270 if (status != PJ_SUCCESS) 271 return status; 272 273 263 274 /* Done */ 264 275 … … 365 376 suspend_sound(conf); 366 377 destroy_sound(conf); 378 pj_mutex_destroy(conf->mutex); 367 379 368 380 return PJ_SUCCESS; … … 386 398 PJ_EINVAL); 387 399 400 pj_mutex_lock(conf->mutex); 401 388 402 if (conf->port_cnt >= conf->max_ports) { 389 403 pj_assert(!"Too many ports"); 404 pj_mutex_unlock(conf->mutex); 390 405 return PJ_ETOOMANY; 391 406 } … … 401 416 /* Create port structure. */ 402 417 status = create_conf_port(pool, conf, port_name, &conf_port); 403 if (status != PJ_SUCCESS) 418 if (status != PJ_SUCCESS) { 419 pj_mutex_unlock(conf->mutex); 404 420 return status; 421 } 405 422 406 423 /* Set the port */ … … 413 430 /* Done. */ 414 431 *p_port = index; 432 433 pj_mutex_unlock(conf->mutex); 415 434 416 435 return PJ_SUCCESS; … … 462 481 PJ_ASSERT_RETURN(conf->ports[src_slot] != NULL, PJ_EINVAL); 463 482 PJ_ASSERT_RETURN(conf->ports[sink_slot] != NULL, PJ_EINVAL); 483 484 pj_mutex_lock(conf->mutex); 464 485 465 486 src_port = conf->ports[src_slot]; … … 481 502 } 482 503 504 pj_mutex_unlock(conf->mutex); 505 483 506 return PJ_SUCCESS; 484 507 } … … 501 524 PJ_ASSERT_RETURN(conf->ports[src_slot] != NULL, PJ_EINVAL); 502 525 PJ_ASSERT_RETURN(conf->ports[sink_slot] != NULL, PJ_EINVAL); 526 527 pj_mutex_lock(conf->mutex); 503 528 504 529 src_port = conf->ports[src_slot]; … … 522 547 } 523 548 549 pj_mutex_unlock(conf->mutex); 550 524 551 return PJ_SUCCESS; 525 552 } … … 545 572 * device's threads! 546 573 */ 547 //suspend_sound(conf); 574 575 pj_mutex_lock(conf->mutex); 548 576 549 577 conf_port = conf->ports[port]; … … 578 606 --conf->port_cnt; 579 607 580 /* Reactivate sound device if there are connections */ 581 if (conf->connect_cnt != 0) { 582 //resume_sound(conf); 583 } else { 608 /* Stop sound if there's no connection. */ 609 if (conf->connect_cnt == 0) { 584 610 destroy_sound(conf); 585 611 } 586 612 587 pj_thread_sleep(60); 613 pj_mutex_unlock(conf->mutex); 614 588 615 return PJ_SUCCESS; 589 616 } … … 659 686 pjmedia_conf *conf = user_data; 660 687 pj_int16_t *output_buf = output; 661 unsigned i, j;688 unsigned ci, cj, i, j; 662 689 663 690 PJ_UNUSED_ARG(timestamp); … … 666 693 TRACE_(("p")); 667 694 668 /* Clear all port's tmp buffers. */ 669 for (i=0; i<conf->max_ports; ++i) { 695 pj_mutex_lock(conf->mutex); 696 697 /* Zero all port's temporary buffers. */ 698 for (i=0, ci=0; i<conf->max_ports && ci < conf->port_cnt; ++i) { 670 699 struct conf_port *conf_port = conf->ports[i]; 671 700 pj_uint32_t *sum_buf; 672 701 702 /* Skip empty slot. */ 673 703 if (!conf_port) 674 704 continue; 705 706 ++ci; 675 707 676 708 conf_port->sources = 0; … … 681 713 } 682 714 683 /* Get frames from all ports, and " add" the signal715 /* Get frames from all ports, and "mix" the signal 684 716 * to sum_buf of all listeners of the port. 685 717 */ 686 for (i=0 ; i<conf->max_ports; ++i) {718 for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 687 719 struct conf_port *conf_port = conf->ports[i]; 688 720 pj_int32_t level; 689 pj_bool_t silence;690 721 691 722 /* Skip empty port. */ … … 693 724 continue; 694 725 726 ++ci; 727 695 728 /* Skip if we're not allowed to receive from this port. */ 696 729 if (conf_port->rx_setting == PJMEDIA_PORT_DISABLE) { 697 TRACE_(("rxdis:%d ", i));698 730 continue; 699 731 } 700 732 701 733 /* Get frame from this port. 702 * If port has rx_buffer (e.g. sound port), then get the frame703 * from the rx_bufferinstead.734 * For port zero (sound port), get the frame from the rx_buffer 735 * instead. 704 736 */ 705 737 if (i==0) { … … 712 744 } 713 745 746 /* Skip if this port is muted/disabled. */ 747 if (conf_port->rx_setting != PJMEDIA_PORT_ENABLE) { 748 continue; 749 } 750 751 752 /* Skip if no port is listening to the microphone */ 753 if (conf_port->listener_cnt == 0) { 754 continue; 755 } 756 714 757 rx_buf = conf_port->rx_buf[conf_port->rx_read]; 715 758 for (j=0; j<conf->samples_per_frame; ++j) { … … 726 769 pjmedia_port_get_frame(conf_port->port, &frame); 727 770 728 771 if (frame.type == PJMEDIA_FRAME_TYPE_NONE) 729 772 continue; 730 773 } … … 738 781 continue; 739 782 740 /* Do we have signal? */ 741 silence = pjmedia_silence_det_detect_silence(conf_port->vad, 742 output, 743 conf->samples_per_frame, 744 &level); 745 746 /* Skip if we don't have signal. */ 747 if (silence) { 748 TRACE_(("sil:%d ", i)); 749 continue; 750 } 751 752 /* Convert the buffer to unsigned value */ 783 /* Get the signal level. */ 784 level = pjmedia_calc_avg_signal(output, conf->samples_per_frame); 785 786 /* Convert level to 8bit complement ulaw */ 787 level = linear2ulaw(level) ^ 0xff; 788 789 /* Convert the buffer to unsigned 16bit value */ 753 790 for (j=0; j<conf->samples_per_frame; ++j) 754 791 conf->uns_buf[j] = pcm2unsigned(((pj_int16_t*)output)[j]); 755 792 756 793 /* Add the signal to all listeners. */ 757 for (j=0; j<conf->max_ports; ++j) { 794 for (j=0, cj=0; 795 j<conf->max_ports && cj<(unsigned)conf_port->listener_cnt; 796 ++j) 797 { 758 798 struct conf_port *listener = conf->ports[j]; 759 799 pj_uint32_t *sum_buf; … … 763 803 continue; 764 804 805 /* Skip if this is not the listener. */ 806 if (!conf_port->listeners[j]) 807 continue; 808 809 ++cj; 810 765 811 /* Skip if this listener doesn't want to receive audio */ 766 812 if (listener->tx_setting != PJMEDIA_PORT_ENABLE) 767 813 continue; 768 814 769 //TRACE_(("mix:%d->%d ", i, j)); 770 815 /* Mix the buffer */ 771 816 sum_buf = listener->sum_buf; 772 817 for (k=0; k<conf->samples_per_frame; ++k) 773 sum_buf[k] += conf->uns_buf[k];774 775 listener->sources ++;818 sum_buf[k] += (conf->uns_buf[k] * level); 819 820 listener->sources += level; 776 821 } 777 822 } 778 823 779 824 /* For all ports, calculate avg signal. */ 780 for (i=0 ; i<conf->max_ports; ++i) {825 for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 781 826 struct conf_port *conf_port = conf->ports[i]; 782 827 pjmedia_frame frame; … … 785 830 if (!conf_port) 786 831 continue; 832 833 ++ci; 787 834 788 835 if (conf_port->tx_setting == PJMEDIA_PORT_MUTE) { … … 800 847 } 801 848 802 //803 // TODO:804 // When there's no source, not transmit the frame, but instead805 // transmit a 'silence' frame. This is to allow the 'port' to806 // do some processing, such as updating timestamp for RTP session807 // or transmit signal when it's in the middle of transmitting DTMF.808 //809 810 849 target_buf = (conf_port->cur_tx_buf==conf_port->tx_buf1? 811 850 conf_port->tx_buf2 : conf_port->tx_buf1); … … 813 852 if (conf_port->sources) { 814 853 for (j=0; j<conf->samples_per_frame; ++j) { 815 target_buf[j] = unsigned2pcm(conf_port->sum_buf[j] / conf_port->sources); 854 target_buf[j] = unsigned2pcm(conf_port->sum_buf[j] / 855 conf_port->sources); 816 856 } 817 857 } … … 821 861 822 862 pj_memset(&frame, 0, sizeof(frame)); 823 if (conf_port->sources) 824 frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 825 else 863 if (conf_port->sources) { 864 865 pj_bool_t is_silence = PJ_FALSE; 866 867 /* Apply silence detection. */ 868 #if 0 869 is_silence = pjmedia_silence_det_detect(conf_port->vad, 870 target_buf, 871 conf->samples_per_frame, 872 NULL); 873 #endif 874 frame.type = is_silence ? PJMEDIA_FRAME_TYPE_NONE : 875 PJMEDIA_FRAME_TYPE_AUDIO; 876 877 } else 826 878 frame.type = PJMEDIA_FRAME_TYPE_NONE; 827 879 … … 836 888 837 889 /* Return sound playback frame. */ 838 for (j=0; j<conf->samples_per_frame; ++j) 839 output_buf[j] = conf->ports[0]->cur_tx_buf[j]; 890 if (conf->ports[0]->sources) { 891 for (j=0; j<conf->samples_per_frame; ++j) 892 output_buf[j] = conf->ports[0]->cur_tx_buf[j]; 893 } else { 894 for (j=0; j<conf->samples_per_frame; ++j) 895 output_buf[j] = 0; 896 } 897 898 pj_mutex_unlock(conf->mutex); 840 899 841 900 return PJ_SUCCESS; … … 863 922 TRACE_(("rxerr ")); 864 923 } 924 925 /* Skip if this port is muted/disabled. */ 926 if (snd_port->rx_setting != PJMEDIA_PORT_ENABLE) 927 return PJ_SUCCESS; 928 929 /* Skip if no port is listening to the microphone */ 930 if (snd_port->listener_cnt == 0) 931 return PJ_SUCCESS; 865 932 866 933 -
pjproject/trunk/pjmedia/src/pjmedia/jbuf.c
r228 r229 24 24 #include <pj/pool.h> 25 25 #include <pj/assert.h> 26 #include <pj/log.h> 26 27 #include <pj/string.h> 27 28 29 30 #define THIS_FILE "jbuf.c" 28 31 29 32 … … 55 58 int jb_max_hist_jitter; // max jitter during the last jitter calculations 56 59 int jb_stable_hist; // num of times the delay has been lower then the prefetch num 60 unsigned jb_op_count; // of of operations. 57 61 int jb_last_op; // last operation executed on the framelist->flist_buffer (put/get) 58 62 int jb_last_seq_no; // seq no. of the last frame inserted to the framelist->flist_buffer … … 293 297 jb->jb_last_level = jb->jb_level; 294 298 jb->jb_max_hist_jitter = PJ_MAX(jb->jb_max_hist_jitter,jb->jb_last_jitter); 295 296 if (jb->jb_last_jitter< jb->jb_prefetch) { 299 jb->jb_op_count++; 300 301 if (jb->jb_last_jitter < jb->jb_prefetch) { 297 302 jb->jb_stable_hist += jb->jb_last_jitter; 298 303 if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { … … 305 310 jb->jb_stable_hist = 0; 306 311 jb->jb_max_hist_jitter = 0; 312 313 if (jb->jb_op_count >= 100 && 314 (int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) 315 { 316 jb_framelist_remove_head(&jb->jb_framelist,1); 317 318 PJ_LOG(5,(THIS_FILE, "jbuf prefetch: %d, size=%d", 319 jb->jb_prefetch, 320 jb_framelist_size(&jb->jb_framelist))); 321 jb->jb_op_count = 0; 322 } 323 307 324 } 308 325 } else { … … 310 327 jb->jb_stable_hist = 0; 311 328 jb->jb_max_hist_jitter = 0; 329 330 if (jb->jb_op_count >= 100) { 331 if ((int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) { 332 jb_framelist_remove_head(&jb->jb_framelist,1); 333 334 PJ_LOG(5,(THIS_FILE, "jbuf prefetch: %d, size=%d", 335 jb->jb_prefetch, 336 jb_framelist_size(&jb->jb_framelist))); 337 } 338 339 jb->jb_op_count = 0; 340 } 312 341 } 313 342 } -
pjproject/trunk/pjmedia/src/pjmedia/silencedet.c
r228 r229 120 120 121 121 122 PJ_DEF(pj_int32_t) pjmedia_ silence_det_calc_avg_signal(const pj_int16_t samples[],123 122 PJ_DEF(pj_int32_t) pjmedia_calc_avg_signal( const pj_int16_t samples[], 123 pj_size_t count) 124 124 { 125 125 pj_uint32_t sum = 0; … … 141 141 } 142 142 143 PJ_DEF(pj_bool_t) pjmedia_silence_det_detect_silence( pjmedia_silence_det *sd, 144 const pj_int16_t samples[], 145 pj_size_t count, 146 pj_int32_t *p_level) 147 { 148 pj_uint32_t level; 143 PJ_DEF(pj_bool_t) pjmedia_silence_det_apply( pjmedia_silence_det *sd, 144 pj_uint32_t level) 145 { 149 146 pj_bool_t have_signal; 150 147 151 148 /* Always return false if VAD is disabled */ 152 if (sd->mode == VAD_MODE_NONE) { 153 if (p_level) 154 *p_level = -1; 149 if (sd->mode == VAD_MODE_NONE) 155 150 return PJ_FALSE; 156 }157 158 /* Calculate average signal level. */159 level = pjmedia_silence_det_calc_avg_signal(samples, count);160 161 /* Report to caller, if required. */162 if (p_level)163 *p_level = level;164 151 165 152 /* Convert PCM level to ulaw */ … … 266 253 267 254 return !sd->in_talk; 268 } 269 255 256 } 257 258 259 PJ_DEF(pj_bool_t) pjmedia_silence_det_detect( pjmedia_silence_det *sd, 260 const pj_int16_t samples[], 261 pj_size_t count, 262 pj_int32_t *p_level) 263 { 264 pj_uint32_t level; 265 266 /* Calculate average signal level. */ 267 level = pjmedia_calc_avg_signal(samples, count); 268 269 /* Report to caller, if required. */ 270 if (p_level) 271 *p_level = level; 272 273 return pjmedia_silence_det_apply(sd, level); 274 } 275 -
pjproject/trunk/pjmedia/src/pjmedia/stream.c
r228 r229 305 305 return status; 306 306 } 307 308 //printf("p"); fflush(stdout); 307 309 308 310 /* Encapsulate. */
Note: See TracChangeset
for help on using the changeset viewer.