Changeset 2850 for pjproject/trunk/pjmedia/src/pjmedia/wsola.c
- Timestamp:
- Aug 1, 2009 9:20:59 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/wsola.c
r2660 r2850 71 71 72 72 /* Template size, in msec */ 73 #define TEMPLATE_PTIME 573 #define TEMPLATE_PTIME PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC 74 74 75 75 /* Hanning window size, in msec */ 76 #define HANNING_PTIME 576 #define HANNING_PTIME PJMEDIA_WSOLA_DELAY_MSEC 77 77 78 78 /* Number of frames in erase buffer */ … … 84 84 /* Maximum distance from template for find_pitch() of expansion, in frames */ 85 85 #define EXP_MAX_DIST HIST_CNT 86 87 /* Duration of a continuous synthetic frames after which the volume 88 * of the synthetic frame will be set to zero with fading-out effect. 89 */ 90 #define MAX_EXPAND_MSEC PJMEDIA_WSOLA_MAX_EXPAND_MSEC 86 91 87 92 … … 132 137 133 138 pj_uint16_t min_extra; /* Minimum extra (const) */ 134 pj_uint16_t expand_cnt; /* Consecutive expansion count */ 139 unsigned max_expand_cnt; /* Max # of synthetic samples */ 140 unsigned fade_out_pos; /* Last fade-out position */ 135 141 pj_uint16_t expand_sr_min_dist;/* Minimum distance from template 136 142 for find_pitch() on expansion … … 147 153 148 154 pj_timestamp ts; /* Running timestamp. */ 155 149 156 }; 150 157 … … 433 440 #endif /* PJ_HAS_FLOATING_POINT */ 434 441 442 /* Apply fade-in to the buffer. 443 * - fade_cnt is the number of samples on which the volume 444 * will go from zero to 100% 445 * - fade_pos is current sample position within fade_cnt range. 446 * It is zero for the first sample, so the first sample will 447 * have zero volume. This value is increasing. 448 */ 449 static void fade_in(pj_int16_t buf[], int count, 450 int fade_in_pos, int fade_cnt) 451 { 452 #if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 453 float fade_pos = (float)fade_in_pos; 454 #else 455 int fade_pos = fade_in_pos; 456 #endif 457 458 if (fade_cnt - fade_pos < count) { 459 for (; fade_pos < fade_cnt; ++fade_pos, ++buf) { 460 *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt); 461 } 462 /* Leave the remaining samples as is */ 463 } else { 464 pj_int16_t *end = buf + count; 465 for (; buf != end; ++fade_pos, ++buf) { 466 *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt); 467 } 468 } 469 } 470 471 /* Apply fade-out to the buffer. */ 472 static void wsola_fade_out(pjmedia_wsola *wsola, 473 pj_int16_t buf[], int count) 474 { 475 pj_int16_t *end = buf + count; 476 int fade_cnt = wsola->max_expand_cnt; 477 #if defined(PJ_HAS_FLOATING_POINT) && PJ_HAS_FLOATING_POINT!=0 478 float fade_pos = (float)wsola->fade_out_pos; 479 #else 480 int fade_pos = wsola->fade_out_pos; 481 #endif 482 483 if (wsola->fade_out_pos == 0) { 484 pjmedia_zero_samples(buf, count); 485 } else if (fade_pos < count) { 486 for (; fade_pos; --fade_pos, ++buf) { 487 *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt); 488 } 489 if (buf != end) 490 pjmedia_zero_samples(buf, end - buf); 491 wsola->fade_out_pos = 0; 492 } else { 493 for (; buf != end; --fade_pos, ++buf) { 494 *buf = (pj_int16_t)(*buf * fade_pos / fade_cnt); 495 } 496 wsola->fade_out_pos -= count; 497 } 498 } 499 435 500 436 501 PJ_DEF(pj_status_t) pjmedia_wsola_create( pj_pool_t *pool, … … 456 521 wsola->channel_count = (pj_uint16_t) channel_count; 457 522 wsola->options = (pj_uint16_t) options; 523 wsola->max_expand_cnt = clock_rate * MAX_EXPAND_MSEC / 1000; 524 wsola->fade_out_pos = wsola->max_expand_cnt; 458 525 459 526 /* Create circular buffer */ … … 524 591 } 525 592 593 PJ_DEF(pj_status_t) pjmedia_wsola_set_max_expand(pjmedia_wsola *wsola, 594 unsigned msec) 595 { 596 PJ_ASSERT_RETURN(wsola, PJ_EINVAL); 597 wsola->max_expand_cnt = msec * wsola->clock_rate / 1000; 598 return PJ_SUCCESS; 599 } 526 600 527 601 PJ_DEF(pj_status_t) pjmedia_wsola_reset( pjmedia_wsola *wsola, … … 534 608 pjmedia_circ_buf_set_len(wsola->buf, wsola->hist_size + wsola->min_extra); 535 609 pjmedia_zero_samples(wsola->buf->start, wsola->buf->len); 610 wsola->fade_out_pos = wsola->max_expand_cnt; 536 611 537 612 return PJ_SUCCESS; … … 683 758 684 759 /* Update vars */ 685 wsola->expand_cnt = 0;686 760 wsola->ts.u64 += wsola->samples_per_frame; 687 761 … … 692 766 pj_int16_t *ola_left; 693 767 768 /* Trim excessive len */ 769 if ((int)buf_len > wsola->hist_size + (wsola->min_extra<<1)) { 770 buf_len = wsola->hist_size + (wsola->min_extra<<1); 771 pjmedia_circ_buf_set_len(wsola->buf, buf_len); 772 } 773 694 774 pjmedia_circ_buf_get_read_regions(wsola->buf, ®1, ®1_len, 695 775 ®2, ®2_len); … … 698 778 (unsigned)(wsola->hist_size + (wsola->min_extra<<1))); 699 779 780 /* Continue applying fade out to the extra samples */ 781 if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) { 782 if (reg2_len == 0) { 783 wsola_fade_out(wsola, reg1 + reg1_len - (wsola->min_extra<<1), 784 (wsola->min_extra<<1)); 785 } else if ((int)reg2_len >= (wsola->min_extra<<1)) { 786 wsola_fade_out(wsola, reg2 + reg2_len - (wsola->min_extra<<1), 787 (wsola->min_extra<<1)); 788 } else { 789 unsigned tmp = (wsola->min_extra<<1) - reg2_len; 790 wsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp); 791 wsola_fade_out(wsola, reg2, reg2_len); 792 } 793 } 794 795 /* Get the region in buffer to be merged with the frame */ 700 796 if (reg2_len == 0) { 701 797 ola_left = reg1 + reg1_len - wsola->min_extra; … … 711 807 } 712 808 809 /* Apply fade-in to the frame before merging */ 810 if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) { 811 unsigned count = wsola->min_extra; 812 int fade_in_pos; 813 814 /* Scale fade_in position based on last fade-out */ 815 fade_in_pos = wsola->fade_out_pos * count / 816 wsola->max_expand_cnt; 817 818 /* Fade-in it */ 819 fade_in(frm, wsola->samples_per_frame, 820 fade_in_pos, count); 821 } 822 823 /* Merge it */ 713 824 overlapp_add_simple(frm, wsola->min_extra, ola_left, frm); 714 825 826 /* Trim len */ 715 827 buf_len -= wsola->min_extra; 716 828 pjmedia_circ_buf_set_len(wsola->buf, buf_len); 717 } 829 830 } else if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0 && 831 wsola->fade_out_pos != wsola->max_expand_cnt) 832 { 833 unsigned count = wsola->min_extra; 834 int fade_in_pos; 835 836 /* Fade out the remaining synthetic samples */ 837 if (buf_len > wsola->hist_size) { 838 pj_int16_t *reg1, *reg2; 839 unsigned reg1_len, reg2_len; 840 841 /* Number of samples to fade out */ 842 count = buf_len - wsola->hist_size; 843 844 pjmedia_circ_buf_get_read_regions(wsola->buf, ®1, ®1_len, 845 ®2, ®2_len); 846 847 CHECK_(pjmedia_circ_buf_get_len(wsola->buf) >= 848 (unsigned)(wsola->hist_size + (wsola->min_extra<<1))); 849 850 /* Continue applying fade out to the extra samples */ 851 if (reg2_len == 0) { 852 wsola_fade_out(wsola, reg1 + reg1_len - count, count); 853 } else if ((int)reg2_len >= count) { 854 wsola_fade_out(wsola, reg2 + reg2_len - count, count); 855 } else { 856 unsigned tmp = count - reg2_len; 857 wsola_fade_out(wsola, reg1 + reg1_len - tmp, tmp); 858 wsola_fade_out(wsola, reg2, reg2_len); 859 } 860 } 861 862 /* Apply fade-in to the frame */ 863 count = wsola->min_extra; 864 865 /* Scale fade_in position based on last fade-out */ 866 fade_in_pos = wsola->fade_out_pos * count / 867 wsola->max_expand_cnt; 868 869 /* Fade it in */ 870 fade_in(frm, wsola->samples_per_frame, 871 fade_in_pos, count); 872 873 } 874 875 wsola->fade_out_pos = wsola->max_expand_cnt; 718 876 719 877 status = pjmedia_circ_buf_write(wsola->buf, frm, wsola->samples_per_frame); … … 738 896 { 739 897 unsigned samples_len, samples_req; 740 741 742 898 pj_status_t status = PJ_SUCCESS; 743 899 … … 758 914 TRACE_((THIS_FILE, "Buf size after expanded = %d", 759 915 pjmedia_circ_buf_get_len(wsola->buf))); 760 wsola->expand_cnt++;761 916 } 762 917 … … 769 924 770 925 pjmedia_circ_buf_adv_read_ptr(wsola->buf, wsola->samples_per_frame); 926 927 /* Apply fade-out to the frame */ 928 if ((wsola->options & PJMEDIA_WSOLA_NO_FADING)==0) { 929 wsola_fade_out(wsola, frm, wsola->samples_per_frame); 930 } 771 931 772 932 return PJ_SUCCESS;
Note: See TracChangeset
for help on using the changeset viewer.