- Timestamp:
- Feb 9, 2009 10:39:58 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2439 r2444 99 99 pj_int16_t *rec_buf; 100 100 pj_uint16_t rec_buf_len; 101 void *strm_data; 101 102 }; 102 103 … … 696 697 } 697 698 699 /* Pack/unpack G.729 frame of S60 DSP codec, taken from: 700 * http://wiki.forum.nokia.com/index.php/TSS000776_-_Payload_conversion_for_G.729_audio_format 701 */ 702 #include "s60_g729_bitstream.h" 703 #include <pjmedia-codec/amr_helper.h> 704 698 705 static void RecCb(TAPSCommBuffer &buf, void *user_data) 699 706 { 700 707 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 701 708 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf; 702 unsigned samples_processed = 0; 703 709 704 710 switch(strm->setting.format.u32) { 705 706 case PJMEDIA_FOURCC_G711U: 707 case PJMEDIA_FOURCC_G711A: 708 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 709 710 /* Detect the recorder G.711 frame size, player frame size will follow 711 * this recorder frame size. 712 */ 713 if (aps_g711_frame_len == 0) { 714 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 715 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 716 aps_g711_frame_len)); 717 } 718 719 /* Convert APS buffer format into pjmedia_frame_ext. Whenever 720 * samples count in the frame is equal to stream's samples per frame, 721 * call parent stream callback. 722 */ 723 while (samples_processed < aps_g711_frame_len) { 724 unsigned tmp; 725 const pj_uint8_t *pb = (const pj_uint8_t*)buf.iBuffer.Ptr() + 2 + 726 samples_processed; 727 728 tmp = PJ_MIN(strm->samples_per_frame - frame->samples_cnt, 729 aps_g711_frame_len - samples_processed); 711 case PJMEDIA_FOURCC_AMR: 712 { 713 const pj_uint8_t *p = (const pj_uint8_t*)buf.iBuffer.Ptr() + 1; 714 unsigned len = buf.iBuffer.Length() - 1; 730 715 731 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 732 samples_processed += tmp; 733 716 pjmedia_frame_ext_append_subframe(frame, p, len << 3, 160); 734 717 if (frame->samples_cnt == strm->samples_per_frame) { 735 718 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; … … 741 724 break; 742 725 726 case PJMEDIA_FOURCC_G729: 727 { 728 /* Check if we got a normal or SID frame. */ 729 if (buf.iBuffer[0] != 0 || buf.iBuffer[1] != 0) { 730 enum { NORMAL_LEN = 22, SID_LEN = 8 }; 731 TBitStream *bitstream = (TBitStream*)strm->strm_data; 732 unsigned src_len = buf.iBuffer.Length()- 2; 733 734 pj_assert(src_len == NORMAL_LEN || src_len == SID_LEN); 735 736 const TDesC8& p = bitstream->CompressG729Frame( 737 buf.iBuffer.Right(src_len), 738 src_len == SID_LEN); 739 740 pjmedia_frame_ext_append_subframe(frame, p.Ptr(), 741 p.Length() << 3, 80); 742 } else { /* We got null frame. */ 743 pjmedia_frame_ext_append_subframe(frame, NULL, 0, 80); 744 } 745 746 if (frame->samples_cnt == strm->samples_per_frame) { 747 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 748 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 749 frame->samples_cnt = 0; 750 frame->subframe_cnt = 0; 751 } 752 } 753 break; 754 755 case PJMEDIA_FOURCC_ILBC: 756 { 757 unsigned samples_got; 758 759 samples_got = strm->setting.mode == 30? 240 : 160; 760 761 /* Check if we got a normal frame. */ 762 if (buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0) { 763 const pj_uint8_t *p = (const pj_uint8_t*)buf.iBuffer.Ptr() + 2; 764 unsigned len = buf.iBuffer.Length() - 2; 765 766 pjmedia_frame_ext_append_subframe(frame, p, len << 3, 767 samples_got); 768 } else { /* We got null frame. */ 769 pjmedia_frame_ext_append_subframe(frame, NULL, 0, samples_got); 770 } 771 772 if (frame->samples_cnt == strm->samples_per_frame) { 773 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 774 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 775 frame->samples_cnt = 0; 776 frame->subframe_cnt = 0; 777 } 778 } 779 break; 780 781 case PJMEDIA_FOURCC_G711U: 782 case PJMEDIA_FOURCC_G711A: 783 { 784 unsigned samples_processed = 0; 785 786 /* Make sure it is normal frame. */ 787 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 788 789 /* Detect the recorder G.711 frame size, player frame size will 790 * follow this recorder frame size. 791 */ 792 if (aps_g711_frame_len == 0) { 793 aps_g711_frame_len = buf.iBuffer.Length() < 160? 80 : 160; 794 TRACE_((THIS_FILE, "Detected APS G.711 frame size = %u samples", 795 aps_g711_frame_len)); 796 } 797 798 /* Convert APS buffer format into pjmedia_frame_ext. Whenever 799 * samples count in the frame is equal to stream's samples per 800 * frame, call parent stream callback. 801 */ 802 while (samples_processed < aps_g711_frame_len) { 803 unsigned tmp; 804 const pj_uint8_t *pb = (const pj_uint8_t*)buf.iBuffer.Ptr() + 805 2 + samples_processed; 806 807 tmp = PJ_MIN(strm->samples_per_frame - frame->samples_cnt, 808 aps_g711_frame_len - samples_processed); 809 810 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 811 samples_processed += tmp; 812 813 if (frame->samples_cnt == strm->samples_per_frame) { 814 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 815 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 816 frame->samples_cnt = 0; 817 frame->subframe_cnt = 0; 818 } 819 } 820 } 821 break; 822 743 823 default: 744 824 break; … … 750 830 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 751 831 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->play_buf; 752 unsigned g711_frame_len = aps_g711_frame_len;753 unsigned samples_ready = 0;754 832 755 833 /* Init buffer attributes and header. */ … … 759 837 760 838 switch(strm->setting.format.u32) { 839 case PJMEDIA_FOURCC_AMR: 840 { 841 if (frame->samples_cnt == 0) { 842 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 843 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 844 845 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 846 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 847 } 848 849 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 850 pjmedia_frame_ext_subframe *sf; 851 unsigned samples_cnt; 852 853 sf = pjmedia_frame_ext_get_subframe(frame, 0); 854 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 855 856 if (sf->data && sf->bitlen) { 857 /* AMR header for APS is one byte, the format (may be!): 858 * 0xxxxy00, where xxxx:frame type, y:not sure. 859 */ 860 unsigned len = sf->bitlen>>3; 861 enum {SID_FT = 8 }; 862 pj_uint8_t amr_header = 4, ft = SID_FT; 863 864 if (sf->bitlen & 0x07) 865 ++len; 866 867 if (len >= pjmedia_codec_amrnb_framelen[0]) 868 ft = pjmedia_codec_amr_get_mode2(PJ_TRUE, len); 869 870 amr_header |= ft << 3; 871 buf.iBuffer.Append(amr_header); 872 873 buf.iBuffer.Append((TUint8*)sf->data, len); 874 } else { 875 buf.iBuffer.Append(0); 876 } 877 878 pjmedia_frame_ext_pop_subframes(frame, 1); 879 880 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 881 buf.iBuffer.Append(0); 882 883 frame->samples_cnt = 0; 884 frame->subframe_cnt = 0; 885 } 886 } 887 break; 888 889 case PJMEDIA_FOURCC_G729: 890 { 891 if (frame->samples_cnt == 0) { 892 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 893 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 894 895 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 896 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 897 } 898 899 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 900 pjmedia_frame_ext_subframe *sf; 901 unsigned samples_cnt; 902 903 sf = pjmedia_frame_ext_get_subframe(frame, 0); 904 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 905 906 if (sf->data && sf->bitlen) { 907 enum { NORMAL_LEN = 10, SID_LEN = 2 }; 908 pj_bool_t sid_frame = ((sf->bitlen >> 3) == SID_LEN); 909 TBitStream *bitstream = (TBitStream*)strm->strm_data; 910 const TPtrC8 src(sf->data, sf->bitlen>>3); 911 const TDesC8 &dst = bitstream->ExpandG729Frame(src, 912 sid_frame); 913 if (sid_frame) { 914 buf.iBuffer.Append(0); 915 buf.iBuffer.Append(1); 916 } else { 917 buf.iBuffer.Append(1); 918 buf.iBuffer.Append(0); 919 } 920 buf.iBuffer.Append(dst); 921 } else { 922 buf.iBuffer.Append(0); 923 buf.iBuffer.Append(0); 924 } 925 926 pjmedia_frame_ext_pop_subframes(frame, 1); 927 928 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 929 buf.iBuffer.Append(0); 930 buf.iBuffer.Append(0); 931 932 frame->samples_cnt = 0; 933 frame->subframe_cnt = 0; 934 } 935 } 936 break; 937 938 case PJMEDIA_FOURCC_ILBC: 939 { 940 if (frame->samples_cnt == 0) { 941 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 942 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 943 944 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || 945 frame->base.type==PJMEDIA_FRAME_TYPE_NONE); 946 } 947 948 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 949 pjmedia_frame_ext_subframe *sf; 950 unsigned samples_cnt; 951 952 sf = pjmedia_frame_ext_get_subframe(frame, 0); 953 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 954 pj_assert((strm->setting.mode == 30 && samples_cnt == 240) || 955 (strm->setting.mode == 20 && samples_cnt == 160)); 956 957 if (sf->data && sf->bitlen) { 958 buf.iBuffer.Append(1); 959 buf.iBuffer.Append(0); 960 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 961 } else { 962 buf.iBuffer.Append(0); 963 buf.iBuffer.Append(0); 964 } 965 966 pjmedia_frame_ext_pop_subframes(frame, 1); 967 968 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 969 buf.iBuffer.Append(0); 970 buf.iBuffer.Append(0); 971 972 frame->samples_cnt = 0; 973 frame->subframe_cnt = 0; 974 } 975 } 976 break; 977 761 978 case PJMEDIA_FOURCC_G711U: 762 979 case PJMEDIA_FOURCC_G711A: 763 980 { 764 /* Add header. */ 765 buf.iBuffer.Append(1); 766 buf.iBuffer.Append(0); 767 981 unsigned samples_ready = 0; 982 unsigned samples_req = aps_g711_frame_len; 983 768 984 /* Assume frame size is 10ms if frame size hasn't been known. */ 769 if ( g711_frame_len== 0)770 g711_frame_len= 80;985 if (samples_req == 0) 986 samples_req = 80; 771 987 772 988 /* Call parent stream callback to get samples to play. */ 773 while (samples_ready < g711_frame_len) {989 while (samples_ready < samples_req) { 774 990 if (frame->samples_cnt == 0) { 775 991 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 776 strm->play_cb(strm->user_data, 0, strm->play_buf, 777 strm->samples_per_frame<<1); 992 strm->play_cb(strm->user_data, 0, strm->play_buf, 0); 778 993 779 994 pj_assert(frame->base.type==PJMEDIA_FRAME_TYPE_EXTENDED || … … 787 1002 sf = pjmedia_frame_ext_get_subframe(frame, 0); 788 1003 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 789 if (sf->data && sf->bitlen) 1004 if (sf->data && sf->bitlen) { 1005 buf.iBuffer.Append(1); 1006 buf.iBuffer.Append(0); 790 1007 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 791 else { 792 pj_uint8_t silence_code; 793 794 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U) 795 silence_code = pjmedia_linear2ulaw(0); 796 else 797 silence_code = pjmedia_linear2alaw(0); 798 799 buf.iBuffer.AppendFill(silence_code, samples_cnt); 1008 } else { 1009 buf.iBuffer.Append(0); 1010 buf.iBuffer.Append(0); 800 1011 } 801 1012 samples_ready += samples_cnt; … … 804 1015 805 1016 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 806 pj_uint8_t silence_code; 807 808 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U) 809 silence_code = pjmedia_linear2ulaw(0); 810 else 811 silence_code = pjmedia_linear2alaw(0); 812 813 buf.iBuffer.AppendFill(silence_code, 814 g711_frame_len - samples_ready); 815 samples_ready = g711_frame_len; 1017 buf.iBuffer.Append(0); 1018 buf.iBuffer.Append(0); 1019 1020 samples_ready = samples_req; 816 1021 frame->samples_cnt = 0; 817 1022 frame->subframe_cnt = 0; … … 922 1127 } 923 1128 924 aps_setting.vad = strm->setting.format.u32==PJMEDIA_FOURCC_L16? 925 EFalse : strm->setting.vad; 1129 /* Disable VAD on L16 and G711. */ 1130 if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || 1131 strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 1132 strm->setting.format.u32 == PJMEDIA_FOURCC_G711A) 1133 { 1134 aps_setting.vad = EFalse; 1135 } else { 1136 aps_setting.vad = strm->setting.vad; 1137 } 1138 926 1139 aps_setting.plc = strm->setting.plc; 927 1140 aps_setting.cng = strm->setting.cng; … … 958 1171 strm->rec_buf_len = 0; 959 1172 1173 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G729) { 1174 TBitStream *g729_bitstream = new TBitStream; 1175 1176 PJ_ASSERT_RETURN(g729_bitstream, PJ_ENOMEM); 1177 strm->strm_data = (void*)g729_bitstream; 1178 } 1179 960 1180 // Done. 961 1181 *p_snd_strm = strm; … … 984 1204 pj_bzero(&setting, sizeof(setting)); 985 1205 setting.format.u32 = PJMEDIA_FOURCC_L16; 986 setting.bitrate = 128000;987 1206 988 1207 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, … … 1007 1226 pj_bzero(&setting, sizeof(setting)); 1008 1227 setting.format.u32 = PJMEDIA_FOURCC_L16; 1009 setting.bitrate = 128000;1010 1228 1011 1229 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, … … 1033 1251 pj_bzero(&setting, sizeof(setting)); 1034 1252 setting.format.u32 = PJMEDIA_FOURCC_L16; 1035 setting.bitrate = 128000;1036 1253 1037 1254 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, … … 1121 1338 stream->engine = NULL; 1122 1339 1340 if (stream->setting.format.u32 == PJMEDIA_FOURCC_G729) { 1341 TBitStream *g729_bitstream = (TBitStream*)stream->strm_data; 1342 stream->strm_data = NULL; 1343 delete g729_bitstream; 1344 } 1345 1123 1346 pool = stream->pool; 1124 1347 if (pool) {
Note: See TracChangeset
for help on using the changeset viewer.