- Timestamp:
- Feb 5, 2009 10:59:14 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/aps-direct/pjmedia/src/pjmedia/symbian_sound_aps.cpp
r2434 r2438 18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 #include <pjmedia/sound.h> 20 21 #include <pjmedia/symbian_sound_aps.h> 21 #include <pjmedia/sound.h>22 22 #include <pjmedia/alaw_ulaw.h> 23 23 #include <pjmedia/errno.h> 24 #include <pjmedia/port.h> 24 25 #include <pj/assert.h> 25 26 #include <pj/log.h> … … 59 60 /* App UID to open global APS queues to communicate with the APS server. */ 60 61 extern TPtrC APP_UID; 61 62 /* Default setting */63 static pjmedia_snd_aps_setting def_setting;64 62 65 63 /* APS G.711 frame length */ … … 88 86 pjmedia_snd_play_cb play_cb; 89 87 void *user_data; 88 pjmedia_snd_setting setting; 90 89 91 90 // Audio engine … … 405 404 // the client session. 406 405 TTime start, now; 407 enum { APS_CLOSE_WAIT_TIME = 200 }; 406 enum { APS_CLOSE_WAIT_TIME = 200 }; /* in msecs */ 407 408 408 start.UniversalTime(); 409 now.UniversalTime(); 410 while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000) { 409 do { 411 410 pj_symbianos_poll(-1, APS_CLOSE_WAIT_TIME); 412 411 now.UniversalTime(); 413 } 412 } while (now.MicroSecondsFrom(start) < APS_CLOSE_WAIT_TIME * 1000); 414 413 415 414 iSession.Close(); … … 618 617 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 619 618 619 /* Buffer has to contain normal speech. */ 620 620 pj_assert(buf.iBuffer[0] == 1 && buf.iBuffer[1] == 0); 621 621 … … 660 660 unsigned g711_frame_len = aps_g711_frame_len; 661 661 662 /* Init buffer attributes and header. */ 662 663 buf.iCommand = CQueueHandler::EAPSPlayData; 663 664 buf.iStatus = 0; … … 697 698 static void RecCb(TAPSCommBuffer &buf, void *user_data) 698 699 { 700 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 701 pjmedia_frame_ext *frame = (pjmedia_frame_ext*) strm->rec_buf; 702 unsigned samples_processed = 0; 703 704 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); 730 731 pjmedia_frame_ext_append_subframe(frame, pb, tmp << 3, tmp); 732 samples_processed += tmp; 733 734 if (frame->samples_cnt == strm->samples_per_frame) { 735 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 736 strm->rec_cb(strm->user_data, 0, strm->rec_buf, 0); 737 frame->samples_cnt = 0; 738 frame->subframe_cnt = 0; 739 } 740 } 741 break; 742 743 default: 744 break; 745 } 699 746 } 700 747 701 748 static void PlayCb(TAPSCommBuffer &buf, void *user_data) 702 749 { 750 pjmedia_snd_stream *strm = (pjmedia_snd_stream*) user_data; 751 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 755 /* Init buffer attributes and header. */ 756 buf.iCommand = CQueueHandler::EAPSPlayData; 757 buf.iStatus = 0; 758 buf.iBuffer.Zero(); 759 760 switch(strm->setting.format.u32) { 761 762 case PJMEDIA_FOURCC_G711U: 763 case PJMEDIA_FOURCC_G711A: 764 /* Add header. */ 765 buf.iBuffer.Append(1); 766 buf.iBuffer.Append(0); 767 768 /* Assume frame size is 10ms if frame size hasn't been known. */ 769 if (g711_frame_len == 0) 770 g711_frame_len = 80; 771 772 /* Call parent stream callback to get samples to play. */ 773 while (samples_ready < g711_frame_len) { 774 if (frame->samples_cnt == 0) { 775 frame->base.type = PJMEDIA_FRAME_TYPE_EXTENDED; 776 strm->play_cb(strm->user_data, 0, strm->play_buf, 777 strm->samples_per_frame<<1); 778 779 pj_assert(frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED || 780 frame->base.type == PJMEDIA_FRAME_TYPE_NONE); 781 } 782 783 if (frame->base.type == PJMEDIA_FRAME_TYPE_EXTENDED) { 784 pjmedia_frame_ext_subframe *sf; 785 unsigned samples_cnt; 786 787 sf = pjmedia_frame_ext_get_subframe(frame, 0); 788 samples_cnt = frame->samples_cnt / frame->subframe_cnt; 789 if (sf->data && sf->bitlen) 790 buf.iBuffer.Append((TUint8*)sf->data, sf->bitlen>>3); 791 else 792 buf.iBuffer.AppendFill(0, samples_cnt); 793 samples_ready += samples_cnt; 794 795 pjmedia_frame_ext_pop_subframes(frame, 1); 796 797 } else { /* PJMEDIA_FRAME_TYPE_NONE */ 798 buf.iBuffer.AppendFill(0, g711_frame_len - samples_ready); 799 samples_ready = g711_frame_len; 800 frame->samples_cnt = 0; 801 frame->subframe_cnt = 0; 802 } 803 } 804 break; 805 806 default: 807 break; 808 } 809 810 unsigned tes = buf.iBuffer.Length(); 703 811 } 704 812 … … 709 817 { 710 818 snd_pool_factory = factory; 711 712 def_setting.format.u32 = PJMEDIA_FOURCC_L16;713 def_setting.mode = 0;714 def_setting.bitrate = 128000;715 def_setting.plc = PJ_FALSE;716 def_setting.vad = PJ_FALSE;717 def_setting.cng = PJ_FALSE;718 def_setting.loudspk = PJ_FALSE;719 819 720 820 return PJ_SUCCESS; … … 751 851 pjmedia_snd_play_cb play_cb, 752 852 void *user_data, 853 const pjmedia_snd_setting *setting, 753 854 pjmedia_snd_stream **p_snd_strm) 754 855 { 755 856 pj_pool_t *pool; 756 857 pjmedia_snd_stream *strm; 757 CPjAudioSetting setting;858 CPjAudioSetting aps_setting; 758 859 PjAudioCallback aps_rec_cb; 759 860 PjAudioCallback aps_play_cb; … … 779 880 strm->channel_count = channel_count; 780 881 strm->samples_per_frame = samples_per_frame; 882 strm->setting = *setting; 883 884 if (strm->setting.format.u32 == 0) 885 strm->setting.format.u32 = PJMEDIA_FOURCC_L16; 781 886 782 887 /* Set audio engine settings. */ 783 if ( def_setting.format.u32 == PJMEDIA_FOURCC_G711U ||784 def_setting.format.u32 == PJMEDIA_FOURCC_L16)888 if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 889 strm->setting.format.u32 == PJMEDIA_FOURCC_L16) 785 890 { 786 setting.fourcc = TFourCC(KMCPFourCCIdG711);891 aps_setting.fourcc = TFourCC(KMCPFourCCIdG711); 787 892 } else { 788 setting.fourcc = TFourCC(def_setting.format.u32);789 } 790 791 if ( def_setting.format.u32 == PJMEDIA_FOURCC_AMR)893 aps_setting.fourcc = TFourCC(strm->setting.format.u32); 894 } 895 896 if (strm->setting.format.u32 == PJMEDIA_FOURCC_AMR) 792 897 { 793 setting.mode = (TAPSCodecMode)def_setting.bitrate;794 } else if ( def_setting.format.u32 == PJMEDIA_FOURCC_G711U ||795 def_setting.format.u32 == PJMEDIA_FOURCC_L16 ||796 ( def_setting.format.u32 == PJMEDIA_FOURCC_ILBC &&797 def_setting.mode == 30))898 aps_setting.mode = (TAPSCodecMode)strm->setting.bitrate; 899 } else if (strm->setting.format.u32 == PJMEDIA_FOURCC_G711U || 900 strm->setting.format.u32 == PJMEDIA_FOURCC_L16 || 901 (strm->setting.format.u32 == PJMEDIA_FOURCC_ILBC && 902 strm->setting.mode == 30)) 798 903 { 799 setting.mode = EULawOr30ms;904 aps_setting.mode = EULawOr30ms; 800 905 } else { 801 setting.mode = EALawOr20ms; 802 } 803 804 setting.vad = def_setting.vad; 805 setting.plc = def_setting.plc; 806 setting.cng = def_setting.cng; 807 setting.loudspk = def_setting.loudspk; 808 809 if (def_setting.format.u32 == PJMEDIA_FOURCC_AMR || 810 def_setting.format.u32 == PJMEDIA_FOURCC_G711A || 811 def_setting.format.u32 == PJMEDIA_FOURCC_G711U || 812 def_setting.format.u32 == PJMEDIA_FOURCC_G729 || 813 def_setting.format.u32 == PJMEDIA_FOURCC_ILBC) 814 { 906 aps_setting.mode = EALawOr20ms; 907 } 908 909 aps_setting.vad = strm->setting.format.u32==PJMEDIA_FOURCC_L16? 910 EFalse : strm->setting.vad; 911 aps_setting.plc = strm->setting.plc; 912 aps_setting.cng = strm->setting.cng; 913 aps_setting.loudspk = strm->setting.loudspk; 914 915 if (strm->setting.format.u32 == PJMEDIA_FOURCC_L16) { 916 aps_play_cb = &PlayCbPcm; 917 aps_rec_cb = &RecCbPcm; 918 } else { 815 919 aps_play_cb = &PlayCb; 816 920 aps_rec_cb = &RecCb; 817 } else {818 aps_play_cb = &PlayCbPcm;819 aps_rec_cb = &RecCbPcm;820 921 } 821 922 … … 823 924 TRAPD(err, strm->engine = CPjAudioEngine::NewL(strm, 824 925 aps_rec_cb, aps_play_cb, 825 strm, setting));926 strm, aps_setting)); 826 927 if (err != KErrNone) { 827 928 pj_pool_release(pool); … … 834 935 835 936 /* play_buf size is samples per frame. */ 836 strm->play_buf = (pj_int16_t*)pj_pool_ alloc(pool, samples_per_frame << 1);937 strm->play_buf = (pj_int16_t*)pj_pool_zalloc(pool, samples_per_frame << 1); 837 938 strm->play_buf_len = 0; 838 939 strm->play_buf_start = 0; 839 940 840 941 /* rec_buf size is samples per frame. */ 841 strm->rec_buf = (pj_int16_t*)pj_pool_ alloc(pool, samples_per_frame << 1);942 strm->rec_buf = (pj_int16_t*)pj_pool_zalloc(pool, samples_per_frame << 1); 842 943 strm->rec_buf_len = 0; 843 944 … … 861 962 pjmedia_snd_stream **p_snd_strm) 862 963 { 964 pjmedia_snd_setting setting; 965 863 966 if (index < 0) index = 0; 864 967 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 865 968 969 pj_bzero(&setting, sizeof(setting)); 970 setting.format.u32 = PJMEDIA_FOURCC_L16; 971 setting.bitrate = 128000; 972 866 973 return sound_open(PJMEDIA_DIR_CAPTURE, clock_rate, channel_count, 867 974 samples_per_frame, bits_per_sample, rec_cb, NULL, 868 user_data, p_snd_strm);975 user_data, &setting, p_snd_strm); 869 976 } 870 977 … … 878 985 pjmedia_snd_stream **p_snd_strm ) 879 986 { 987 pjmedia_snd_setting setting; 988 880 989 if (index < 0) index = 0; 881 990 PJ_ASSERT_RETURN(index == 0, PJ_EINVAL); 882 991 992 pj_bzero(&setting, sizeof(setting)); 993 setting.format.u32 = PJMEDIA_FOURCC_L16; 994 setting.bitrate = 128000; 995 883 996 return sound_open(PJMEDIA_DIR_PLAYBACK, clock_rate, channel_count, 884 997 samples_per_frame, bits_per_sample, NULL, play_cb, 885 user_data, p_snd_strm);998 user_data, &setting, p_snd_strm); 886 999 } 887 1000 … … 897 1010 pjmedia_snd_stream **p_snd_strm) 898 1011 { 1012 pjmedia_snd_setting setting; 1013 899 1014 if (rec_id < 0) rec_id = 0; 900 1015 if (play_id < 0) play_id = 0; 901 1016 PJ_ASSERT_RETURN(play_id == 0 && rec_id == 0, PJ_EINVAL); 902 1017 1018 pj_bzero(&setting, sizeof(setting)); 1019 setting.format.u32 = PJMEDIA_FOURCC_L16; 1020 setting.bitrate = 128000; 1021 903 1022 return sound_open(PJMEDIA_DIR_CAPTURE_PLAYBACK, clock_rate, channel_count, 904 1023 samples_per_frame, bits_per_sample, rec_cb, play_cb, 905 user_data, p_snd_strm); 1024 user_data, &setting, p_snd_strm); 1025 } 1026 1027 PJ_DEF(pj_status_t) pjmedia_snd_open2( pjmedia_dir dir, 1028 int rec_id, 1029 int play_id, 1030 unsigned clock_rate, 1031 unsigned channel_count, 1032 unsigned samples_per_frame, 1033 unsigned bits_per_sample, 1034 pjmedia_snd_rec_cb rec_cb, 1035 pjmedia_snd_play_cb play_cb, 1036 void *user_data, 1037 const pjmedia_snd_setting *setting, 1038 pjmedia_snd_stream **p_snd_strm) 1039 { 1040 if (rec_id < 0) rec_id = 0; 1041 if (play_id < 0) play_id = 0; 1042 PJ_ASSERT_RETURN(play_id == 0 && rec_id == 0, PJ_EINVAL); 1043 1044 return sound_open(dir, clock_rate, channel_count, 1045 samples_per_frame, bits_per_sample, rec_cb, play_cb, 1046 user_data, setting, p_snd_strm); 906 1047 } 907 1048 … … 994 1135 } 995 1136 996 997 1137 /* 998 1138 * Activate/deactivate loudspeaker. … … 1002 1142 pj_bool_t active) 1003 1143 { 1004 if (stream == NULL) { 1005 def_setting.loudspk = active; 1006 } else { 1007 if (stream->engine == NULL) 1008 return PJ_EINVAL; 1009 1010 TInt err = stream->engine->ActivateSpeaker(active); 1011 if (err != KErrNone) 1012 return PJ_RETURN_OS_ERROR(err); 1013 } 1144 PJ_ASSERT_RETURN(stream && stream->engine, PJ_EINVAL); 1145 1146 TInt err = stream->engine->ActivateSpeaker(active); 1147 if (err != KErrNone) 1148 return PJ_RETURN_OS_ERROR(err); 1014 1149 1015 1150 return PJ_SUCCESS; 1016 1151 } 1017 1152 1018 /**1019 * Set a codec and its settings to be used on the next sound device session.1020 */1021 PJ_DEF(pj_status_t) pjmedia_snd_aps_modify_setting(1022 const pjmedia_snd_aps_setting *setting)1023 {1024 PJ_ASSERT_RETURN(setting, PJ_EINVAL);1025 1026 def_setting = *setting;1027 1028 return PJ_SUCCESS;1029 }1030 1031 1153 #endif // PJMEDIA_SOUND_IMPLEMENTATION == PJMEDIA_SOUND_SYMB_APS_SOUND
Note: See TracChangeset
for help on using the changeset viewer.