- Timestamp:
- Jul 26, 2012 3:31:55 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/android/pjmedia/src/pjmedia-audiodev/opensl_dev.c
r4193 r4215 35 35 #include <SLES/OpenSLES.h> 36 36 #include <SLES/OpenSLES_Android.h> 37 #include <sys/system_properties.h> 38 #include <android/api-level.h> 37 39 38 40 #define THIS_FILE "opensl_dev.c" … … 70 72 pjmedia_aud_play_cb play_cb; 71 73 74 pj_timestamp play_timestamp; 75 pj_timestamp rec_timestamp; 76 72 77 pj_bool_t rec_thread_initialized; 73 78 pj_thread_desc rec_thread_desc; … … 81 86 SLObjectItf playerObj; 82 87 SLPlayItf playerPlay; 88 SLVolumeItf playerVol; 83 89 unsigned playerBufferSize; 84 90 char *playerBuffer[NUM_BUFFERS]; … … 174 180 frame.buf = buf = stream->playerBuffer[stream->playerBufIdx++]; 175 181 frame.size = stream->playerBufferSize; 182 frame.timestamp.u64 = stream->play_timestamp.u64; 176 183 frame.bit_info = 0; 177 184 … … 179 186 if (status != PJ_SUCCESS || frame.type != PJMEDIA_FRAME_TYPE_AUDIO) 180 187 pj_bzero(buf, stream->playerBufferSize); 188 189 stream->play_timestamp.u64 += stream->param.samples_per_frame / 190 stream->param.channel_count; 181 191 182 192 result = (*bq)->Enqueue(bq, buf, stream->playerBufferSize); … … 216 226 frame.buf = buf = stream->recordBuffer[stream->recordBufIdx++]; 217 227 frame.size = stream->recordBufferSize; 218 frame.timestamp.u64 = 0;228 frame.timestamp.u64 = stream->rec_timestamp.u64; 219 229 frame.bit_info = 0; 220 230 221 231 status = (*stream->rec_cb)(stream->user_data, &frame); 232 233 stream->rec_timestamp.u64 += stream->param.samples_per_frame / 234 stream->param.channel_count; 222 235 223 236 /* And now enqueue next buffer */ … … 379 392 380 393 pj_ansi_strcpy(info->name, "OpenSL ES Audio"); 381 info->default_samples_per_sec = 16000; 382 info->caps = PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING | 383 PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; 394 info->default_samples_per_sec = 8000; 395 info->caps = PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; 384 396 info->input_count = 1; 385 397 info->output_count = 1; … … 422 434 param->samples_per_frame = adi.default_samples_per_sec * 20 / 1000; 423 435 param->bits_per_sample = 16; 424 param->flags = adi.caps;425 436 param->input_latency_ms = PJMEDIA_SND_DEFAULT_REC_LATENCY; 426 437 param->output_latency_ms = PJMEDIA_SND_DEFAULT_PLAY_LATENCY; … … 486 497 SLDataSink audioSnk = {&loc_outmix, NULL}; 487 498 /* Audio interface */ 488 const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, 489 SL_IID_VOLUME/*, 490 SL_IID_ANDROIDCONFIGURATION*/}; 491 const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; 499 const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, 500 SL_IID_VOLUME, 501 SL_IID_ANDROIDCONFIGURATION}; 502 const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, 503 SL_BOOLEAN_FALSE}; 504 SLAndroidConfigurationItf playerConfig; 505 SLint32 streamType = SL_ANDROID_STREAM_VOICE; 492 506 493 507 /* Create audio player */ … … 495 509 &stream->playerObj, 496 510 &audioSrc, &audioSnk, 497 2, ids, req);511 3, ids, req); 498 512 if (result != SL_RESULT_SUCCESS) { 499 513 PJ_LOG(3, (THIS_FILE, "Cannot create audio player: %d", result)); … … 501 515 } 502 516 503 /* 504 SLAndroidConfigurationItf playerConfig; 505 SLint32 streamType = SL_ANDROID_STREAM_VOICE; 517 /* Set Android configuration */ 506 518 result = (*stream->playerObj)->GetInterface(stream->playerObj, 507 519 SL_IID_ANDROIDCONFIGURATION, 508 520 &playerConfig); 509 if (result != SL_RESULT_SUCCESS) { 510 PJ_LOG(4, (THIS_FILE, "Cannot get android configuration iface")); 511 } 512 result = (*playerConfig)->SetConfiguration(playerConfig, 513 SL_ANDROID_KEY_STREAM_TYPE, 514 &streamType, 515 sizeof(SLint32)); 516 */ 521 if (result == SL_RESULT_SUCCESS && playerConfig) { 522 result = (*playerConfig)->SetConfiguration( 523 playerConfig, SL_ANDROID_KEY_STREAM_TYPE, 524 &streamType, sizeof(SLint32)); 525 } 526 if (result != SL_RESULT_SUCCESS) { 527 PJ_LOG(4, (THIS_FILE, "Warning: Unable to set android " 528 "player configuration")); 529 } 517 530 518 531 /* Realize the player */ … … 541 554 goto on_error; 542 555 } 556 557 /* Get the volume interface */ 558 result = (*stream->playerObj)->GetInterface(stream->playerObj, 559 SL_IID_VOLUME, 560 &stream->playerVol); 543 561 544 562 /* Register callback on the buffer queue */ … … 569 587 SLDataSink audioSnk = {&loc_bq, &format_pcm}; 570 588 /* Audio interface */ 571 const SLInterfaceID ids[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE}; 572 const SLboolean req[1] = {SL_BOOLEAN_TRUE}; 589 const SLInterfaceID ids[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, 590 SL_IID_ANDROIDCONFIGURATION}; 591 const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE}; 592 SLAndroidConfigurationItf recorderConfig; 573 593 574 594 /* Create audio recorder … … 578 598 &stream->recordObj, 579 599 &audioSrc, &audioSnk, 580 1, ids, req);600 2, ids, req); 581 601 if (result != SL_RESULT_SUCCESS) { 582 602 PJ_LOG(3, (THIS_FILE, "Cannot create recorder: %d", result)); … … 584 604 } 585 605 586 /* 587 SLAndroidConfigurationItf recorderConfig; 606 /* Set Android configuration */ 588 607 result = (*stream->recordObj)->GetInterface(stream->recordObj, 589 608 SL_IID_ANDROIDCONFIGURATION, … … 591 610 if (result == SL_RESULT_SUCCESS) { 592 611 SLint32 streamType = SL_ANDROID_RECORDING_PRESET_GENERIC; 612 #if __ANDROID_API__ >= 14 593 613 char sdk_version[PROP_VALUE_MAX]; 594 614 pj_str_t pj_sdk_version; … … 598 618 pj_sdk_version = pj_str(sdk_version); 599 619 sdk_v = pj_strtoul(&pj_sdk_version); 600 if (sdk_v >= 10) 601 streamType = 0x7; 602 603 PJ_LOG(4, (THIS_FILE, "We have a stream type %d SDK : %d", 620 if (sdk_v >= 14) 621 streamType = SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION; 622 PJ_LOG(4, (THIS_FILE, "Recording stream type %d, SDK : %d", 604 623 streamType, sdk_v)); 624 #endif 605 625 result = (*recorderConfig)->SetConfiguration( 606 626 recorderConfig, SL_ANDROID_KEY_RECORDING_PRESET, 607 627 &streamType, sizeof(SLint32)); 608 } else { 609 PJ_LOG(4, (THIS_FILE, "Cannot get recorder config interface")); 610 } 611 */ 628 } 629 if (result != SL_RESULT_SUCCESS) { 630 PJ_LOG(4, (THIS_FILE, "Warning: Unable to set android " 631 "recorder configuration")); 632 } 612 633 613 634 /* Realize the recorder */ … … 655 676 } 656 677 678 if (param->flags & PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING) { 679 strm_set_cap(&stream->base, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 680 ¶m->output_vol); 681 } 682 657 683 /* Done */ 658 684 stream->base.op = &opensl_strm_op; … … 672 698 PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL); 673 699 pj_memcpy(pi, &strm->param, sizeof(*pi)); 700 701 if (strm_get_cap(s, PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING, 702 &pi->output_vol) == PJ_SUCCESS) 703 { 704 pi->flags |= PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING; 705 } 674 706 675 707 return PJ_SUCCESS; … … 686 718 PJ_ASSERT_RETURN(s && pval, PJ_EINVAL); 687 719 688 PJ_UNUSED_ARG(strm); 689 690 switch (cap) { 691 case PJMEDIA_AUD_DEV_CAP_INPUT_VOLUME_SETTING: 692 status = PJ_SUCCESS; 693 break; 694 case PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING: 695 status = PJ_SUCCESS; 696 break; 697 default: 698 break; 720 if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && 721 (strm->param.dir & PJMEDIA_DIR_PLAYBACK)) 722 { 723 if (strm->playerVol) { 724 SLresult res; 725 SLmillibel vol, mvol; 726 727 res = (*strm->playerVol)->GetMaxVolumeLevel(strm->playerVol, 728 &mvol); 729 if (res == SL_RESULT_SUCCESS) { 730 res = (*strm->playerVol)->GetVolumeLevel(strm->playerVol, 731 &vol); 732 if (res == SL_RESULT_SUCCESS) { 733 *(int *)pval = ((int)vol - SL_MILLIBEL_MIN) * 100 / 734 ((int)mvol - SL_MILLIBEL_MIN); 735 return PJ_SUCCESS; 736 } 737 } 738 } 699 739 } 700 740 … … 703 743 704 744 /* API: set capability */ 705 static pj_status_t strm_set_cap(pjmedia_aud_stream *s trm,745 static pj_status_t strm_set_cap(pjmedia_aud_stream *s, 706 746 pjmedia_aud_dev_cap cap, 707 747 const void *value) 708 748 { 709 PJ_UNUSED_ARG(strm); 710 PJ_UNUSED_ARG(cap); 711 PJ_UNUSED_ARG(value); 749 struct opensl_aud_stream *strm = (struct opensl_aud_stream*)s; 750 751 PJ_ASSERT_RETURN(s && value, PJ_EINVAL); 752 753 if (cap==PJMEDIA_AUD_DEV_CAP_OUTPUT_VOLUME_SETTING && 754 (strm->param.dir & PJMEDIA_DIR_PLAYBACK)) 755 { 756 if (strm->playerVol) { 757 SLresult res; 758 SLmillibel vol, mvol; 759 760 res = (*strm->playerVol)->GetMaxVolumeLevel(strm->playerVol, 761 &mvol); 762 if (res == SL_RESULT_SUCCESS) { 763 vol = (SLmillibel)(*(int *)value * 764 ((int)mvol - SL_MILLIBEL_MIN) / 100 + SL_MILLIBEL_MIN); 765 res = (*strm->playerVol)->SetVolumeLevel(strm->playerVol, 766 vol); 767 if (res == SL_RESULT_SUCCESS) 768 return PJ_SUCCESS; 769 } 770 } 771 } 712 772 713 773 return PJMEDIA_EAUD_INVCAP; … … 795 855 if (stream->playerBufQ && stream->playerPlay) { 796 856 /* Wait until the PCM data is done playing, the buffer queue callback 797 will continue to queue buffers until the entire PCM data has been798 played. This is indicated by waiting for the count member of the799 SLBufferQueueState to go to zero.857 * will continue to queue buffers until the entire PCM data has been 858 * played. This is indicated by waiting for the count member of the 859 * SLBufferQueueState to go to zero. 800 860 */ 801 861 /* … … 829 889 /* Destroy the player */ 830 890 (*stream->playerObj)->Destroy(stream->playerObj); 891 /* Invalidate all associated interfaces */ 831 892 stream->playerObj = NULL; 832 893 stream->playerPlay = NULL; 833 894 stream->playerBufQ = NULL; 895 stream->playerVol = NULL; 834 896 } 835 897 … … 837 899 /* Destroy the recorder */ 838 900 (*stream->recordObj)->Destroy(stream->recordObj); 901 /* Invalidate all associated interfaces */ 839 902 stream->recordObj = NULL; 840 903 stream->recordRecord = NULL;
Note: See TracChangeset
for help on using the changeset viewer.