| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 } else if (warning == AudioDeviceObserver::kPlayoutWarning) { | 70 } else if (warning == AudioDeviceObserver::kPlayoutWarning) { |
| 71 warningCode = VE_RUNTIME_PLAY_WARNING; | 71 warningCode = VE_RUNTIME_PLAY_WARNING; |
| 72 LOG_F(LS_WARNING) << "VE_RUNTIME_PLAY_WARNING"; | 72 LOG_F(LS_WARNING) << "VE_RUNTIME_PLAY_WARNING"; |
| 73 } | 73 } |
| 74 if (voiceEngineObserverPtr_) { | 74 if (voiceEngineObserverPtr_) { |
| 75 // Deliver callback (-1 <=> no channel dependency) | 75 // Deliver callback (-1 <=> no channel dependency) |
| 76 voiceEngineObserverPtr_->CallbackOnError(-1, warningCode); | 76 voiceEngineObserverPtr_->CallbackOnError(-1, warningCode); |
| 77 } | 77 } |
| 78 } | 78 } |
| 79 | 79 |
| 80 int32_t VoEBaseImpl::RecordedDataIsAvailable(const void* audioSamples, | 80 int32_t VoEBaseImpl::RecordedDataIsAvailable( |
| 81 const size_t nSamples, | 81 const void* audio_data, |
| 82 const size_t nBytesPerSample, | 82 const size_t number_of_frames, |
| 83 const size_t nChannels, | 83 const size_t bytes_per_sample, |
| 84 const uint32_t samplesPerSec, | 84 const size_t number_of_channels, |
| 85 const uint32_t totalDelayMS, | 85 const uint32_t sample_rate, |
| 86 const int32_t clockDrift, | 86 const uint32_t audio_delay_milliseconds, |
| 87 const uint32_t currentMicLevel, | 87 const int32_t clock_drift, |
| 88 const bool keyPressed, | 88 const uint32_t volume, |
| 89 uint32_t& newMicLevel) { | 89 const bool key_pressed, |
| 90 newMicLevel = static_cast<uint32_t>(ProcessRecordedDataWithAPM( | 90 uint32_t& new_mic_volume) { |
| 91 nullptr, 0, audioSamples, samplesPerSec, nChannels, nSamples, | 91 RTC_DCHECK_EQ(2 * number_of_channels, bytes_per_sample); |
| 92 totalDelayMS, clockDrift, currentMicLevel, keyPressed)); | 92 RTC_DCHECK(shared_->transmit_mixer() != nullptr); |
| 93 RTC_DCHECK(shared_->audio_device() != nullptr); |
| 94 |
| 95 uint32_t max_volume = 0; |
| 96 uint16_t voe_mic_level = 0; |
| 97 // Check for zero to skip this calculation; the consumer may use this to |
| 98 // indicate no volume is available. |
| 99 if (volume != 0) { |
| 100 // Scale from ADM to VoE level range |
| 101 if (shared_->audio_device()->MaxMicrophoneVolume(&max_volume) == 0) { |
| 102 if (max_volume) { |
| 103 voe_mic_level = static_cast<uint16_t>( |
| 104 (volume * kMaxVolumeLevel + static_cast<int>(max_volume / 2)) / |
| 105 max_volume); |
| 106 } |
| 107 } |
| 108 // We learned that on certain systems (e.g Linux) the voe_mic_level |
| 109 // can be greater than the maxVolumeLevel therefore |
| 110 // we are going to cap the voe_mic_level to the maxVolumeLevel |
| 111 // and change the maxVolume to volume if it turns out that |
| 112 // the voe_mic_level is indeed greater than the maxVolumeLevel. |
| 113 if (voe_mic_level > kMaxVolumeLevel) { |
| 114 voe_mic_level = kMaxVolumeLevel; |
| 115 max_volume = volume; |
| 116 } |
| 117 } |
| 118 |
| 119 // Perform channel-independent operations |
| 120 // (APM, mix with file, record to file, mute, etc.) |
| 121 shared_->transmit_mixer()->PrepareDemux( |
| 122 audio_data, number_of_frames, number_of_channels, sample_rate, |
| 123 static_cast<uint16_t>(audio_delay_milliseconds), clock_drift, |
| 124 voe_mic_level, key_pressed); |
| 125 |
| 126 // Copy the audio frame to each sending channel and perform |
| 127 // channel-dependent operations (file mixing, mute, etc.), encode and |
| 128 // packetize+transmit the RTP packet. |
| 129 shared_->transmit_mixer()->ProcessAndEncodeAudio(); |
| 130 |
| 131 // Scale from VoE to ADM level range. |
| 132 uint32_t new_voe_mic_level = shared_->transmit_mixer()->CaptureLevel(); |
| 133 if (new_voe_mic_level != voe_mic_level) { |
| 134 // Return the new volume if AGC has changed the volume. |
| 135 return static_cast<int>((new_voe_mic_level * max_volume + |
| 136 static_cast<int>(kMaxVolumeLevel / 2)) / |
| 137 kMaxVolumeLevel); |
| 138 } |
| 139 |
| 93 return 0; | 140 return 0; |
| 94 } | 141 } |
| 95 | 142 |
| 96 int32_t VoEBaseImpl::NeedMorePlayData(const size_t nSamples, | 143 int32_t VoEBaseImpl::NeedMorePlayData(const size_t nSamples, |
| 97 const size_t nBytesPerSample, | 144 const size_t nBytesPerSample, |
| 98 const size_t nChannels, | 145 const size_t nChannels, |
| 99 const uint32_t samplesPerSec, | 146 const uint32_t samplesPerSec, |
| 100 void* audioSamples, | 147 void* audioSamples, |
| 101 size_t& nSamplesOut, | 148 size_t& nSamplesOut, |
| 102 int64_t* elapsed_time_ms, | 149 int64_t* elapsed_time_ms, |
| 103 int64_t* ntp_time_ms) { | 150 int64_t* ntp_time_ms) { |
| 104 GetPlayoutData(static_cast<int>(samplesPerSec), nChannels, nSamples, true, | 151 GetPlayoutData(static_cast<int>(samplesPerSec), nChannels, nSamples, true, |
| 105 audioSamples, elapsed_time_ms, ntp_time_ms); | 152 audioSamples, elapsed_time_ms, ntp_time_ms); |
| 106 nSamplesOut = audioFrame_.samples_per_channel_; | 153 nSamplesOut = audioFrame_.samples_per_channel_; |
| 107 return 0; | 154 return 0; |
| 108 } | 155 } |
| 109 | 156 |
| 110 void VoEBaseImpl::PushCaptureData(int voe_channel, const void* audio_data, | 157 void VoEBaseImpl::PushCaptureData(int voe_channel, const void* audio_data, |
| 111 int bits_per_sample, int sample_rate, | 158 int bits_per_sample, int sample_rate, |
| 112 size_t number_of_channels, | 159 size_t number_of_channels, |
| 113 size_t number_of_frames) { | 160 size_t number_of_frames) { |
| 114 voe::ChannelOwner ch = shared_->channel_manager().GetChannel(voe_channel); | 161 voe::ChannelOwner ch = shared_->channel_manager().GetChannel(voe_channel); |
| 115 voe::Channel* channel_ptr = ch.channel(); | 162 voe::Channel* channel = ch.channel(); |
| 116 if (!channel_ptr) return; | 163 if (!channel) |
| 117 | 164 return; |
| 118 if (channel_ptr->Sending()) { | 165 if (channel->Sending()) { |
| 119 channel_ptr->Demultiplex(static_cast<const int16_t*>(audio_data), | 166 // Send the audio to each channel directly without using the APM in the |
| 120 sample_rate, number_of_frames, number_of_channels); | 167 // transmit mixer. |
| 121 channel_ptr->PrepareEncodeAndSend(sample_rate); | 168 channel->ProcessAndEncodeAudio(static_cast<const int16_t*>(audio_data), |
| 122 channel_ptr->EncodeAndSend(); | 169 sample_rate, number_of_frames, |
| 170 number_of_channels); |
| 123 } | 171 } |
| 124 } | 172 } |
| 125 | 173 |
| 126 void VoEBaseImpl::PullRenderData(int bits_per_sample, | 174 void VoEBaseImpl::PullRenderData(int bits_per_sample, |
| 127 int sample_rate, | 175 int sample_rate, |
| 128 size_t number_of_channels, | 176 size_t number_of_channels, |
| 129 size_t number_of_frames, | 177 size_t number_of_frames, |
| 130 void* audio_data, int64_t* elapsed_time_ms, | 178 void* audio_data, int64_t* elapsed_time_ms, |
| 131 int64_t* ntp_time_ms) { | 179 int64_t* ntp_time_ms) { |
| 132 assert(bits_per_sample == 16); | 180 assert(bits_per_sample == 16); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 config_copy.acm_config.decoder_factory = decoder_factory_; | 418 config_copy.acm_config.decoder_factory = decoder_factory_; |
| 371 voe::ChannelOwner channel_owner = | 419 voe::ChannelOwner channel_owner = |
| 372 shared_->channel_manager().CreateChannel(config_copy); | 420 shared_->channel_manager().CreateChannel(config_copy); |
| 373 return InitializeChannel(&channel_owner); | 421 return InitializeChannel(&channel_owner); |
| 374 } | 422 } |
| 375 | 423 |
| 376 int VoEBaseImpl::InitializeChannel(voe::ChannelOwner* channel_owner) { | 424 int VoEBaseImpl::InitializeChannel(voe::ChannelOwner* channel_owner) { |
| 377 if (channel_owner->channel()->SetEngineInformation( | 425 if (channel_owner->channel()->SetEngineInformation( |
| 378 shared_->statistics(), *shared_->output_mixer(), | 426 shared_->statistics(), *shared_->output_mixer(), |
| 379 *shared_->process_thread(), *shared_->audio_device(), | 427 *shared_->process_thread(), *shared_->audio_device(), |
| 380 voiceEngineObserverPtr_, &callbackCritSect_) != 0) { | 428 voiceEngineObserverPtr_, &callbackCritSect_, |
| 429 shared_->encoder_queue()) != 0) { |
| 381 shared_->SetLastError( | 430 shared_->SetLastError( |
| 382 VE_CHANNEL_NOT_CREATED, kTraceError, | 431 VE_CHANNEL_NOT_CREATED, kTraceError, |
| 383 "CreateChannel() failed to associate engine and channel." | 432 "CreateChannel() failed to associate engine and channel." |
| 384 " Destroying channel."); | 433 " Destroying channel."); |
| 385 shared_->channel_manager().DestroyChannel( | 434 shared_->channel_manager().DestroyChannel( |
| 386 channel_owner->channel()->ChannelId()); | 435 channel_owner->channel()->ChannelId()); |
| 387 return -1; | 436 return -1; |
| 388 } else if (channel_owner->channel()->Init() != 0) { | 437 } else if (channel_owner->channel()->Init() != 0) { |
| 389 shared_->SetLastError( | 438 shared_->SetLastError( |
| 390 VE_CHANNEL_NOT_CREATED, kTraceError, | 439 VE_CHANNEL_NOT_CREATED, kTraceError, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 shared_->SetLastError(VE_NOT_INITED, kTraceError); | 563 shared_->SetLastError(VE_NOT_INITED, kTraceError); |
| 515 return -1; | 564 return -1; |
| 516 } | 565 } |
| 517 voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel); | 566 voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel); |
| 518 voe::Channel* channelPtr = ch.channel(); | 567 voe::Channel* channelPtr = ch.channel(); |
| 519 if (channelPtr == nullptr) { | 568 if (channelPtr == nullptr) { |
| 520 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 569 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, |
| 521 "StopSend() failed to locate channel"); | 570 "StopSend() failed to locate channel"); |
| 522 return -1; | 571 return -1; |
| 523 } | 572 } |
| 524 if (channelPtr->StopSend() != 0) { | 573 channelPtr->StopSend(); |
| 525 LOG_F(LS_WARNING) << "StopSend() failed to stop sending for channel " | |
| 526 << channel; | |
| 527 } | |
| 528 return StopSend(); | 574 return StopSend(); |
| 529 } | 575 } |
| 530 | 576 |
| 531 int VoEBaseImpl::GetVersion(char version[1024]) { | 577 int VoEBaseImpl::GetVersion(char version[1024]) { |
| 532 if (version == nullptr) { | 578 if (version == nullptr) { |
| 533 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError); | 579 shared_->SetLastError(VE_INVALID_ARGUMENT, kTraceError); |
| 534 return -1; | 580 return -1; |
| 535 } | 581 } |
| 536 | 582 |
| 537 std::string versionString = VoiceEngine::GetVersionString(); | 583 std::string versionString = VoiceEngine::GetVersionString(); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 shared_->set_audio_device(nullptr); | 687 shared_->set_audio_device(nullptr); |
| 642 } | 688 } |
| 643 | 689 |
| 644 if (shared_->audio_processing()) { | 690 if (shared_->audio_processing()) { |
| 645 shared_->set_audio_processing(nullptr); | 691 shared_->set_audio_processing(nullptr); |
| 646 } | 692 } |
| 647 | 693 |
| 648 return shared_->statistics().SetUnInitialized(); | 694 return shared_->statistics().SetUnInitialized(); |
| 649 } | 695 } |
| 650 | 696 |
| 651 int VoEBaseImpl::ProcessRecordedDataWithAPM( | |
| 652 const int voe_channels[], size_t number_of_voe_channels, | |
| 653 const void* audio_data, uint32_t sample_rate, size_t number_of_channels, | |
| 654 size_t number_of_frames, uint32_t audio_delay_milliseconds, | |
| 655 int32_t clock_drift, uint32_t volume, bool key_pressed) { | |
| 656 assert(shared_->transmit_mixer() != nullptr); | |
| 657 assert(shared_->audio_device() != nullptr); | |
| 658 | |
| 659 uint32_t max_volume = 0; | |
| 660 uint16_t voe_mic_level = 0; | |
| 661 // Check for zero to skip this calculation; the consumer may use this to | |
| 662 // indicate no volume is available. | |
| 663 if (volume != 0) { | |
| 664 // Scale from ADM to VoE level range | |
| 665 if (shared_->audio_device()->MaxMicrophoneVolume(&max_volume) == 0) { | |
| 666 if (max_volume) { | |
| 667 voe_mic_level = static_cast<uint16_t>( | |
| 668 (volume * kMaxVolumeLevel + static_cast<int>(max_volume / 2)) / | |
| 669 max_volume); | |
| 670 } | |
| 671 } | |
| 672 // We learned that on certain systems (e.g Linux) the voe_mic_level | |
| 673 // can be greater than the maxVolumeLevel therefore | |
| 674 // we are going to cap the voe_mic_level to the maxVolumeLevel | |
| 675 // and change the maxVolume to volume if it turns out that | |
| 676 // the voe_mic_level is indeed greater than the maxVolumeLevel. | |
| 677 if (voe_mic_level > kMaxVolumeLevel) { | |
| 678 voe_mic_level = kMaxVolumeLevel; | |
| 679 max_volume = volume; | |
| 680 } | |
| 681 } | |
| 682 | |
| 683 // Perform channel-independent operations | |
| 684 // (APM, mix with file, record to file, mute, etc.) | |
| 685 shared_->transmit_mixer()->PrepareDemux( | |
| 686 audio_data, number_of_frames, number_of_channels, sample_rate, | |
| 687 static_cast<uint16_t>(audio_delay_milliseconds), clock_drift, | |
| 688 voe_mic_level, key_pressed); | |
| 689 | |
| 690 // Copy the audio frame to each sending channel and perform | |
| 691 // channel-dependent operations (file mixing, mute, etc.), encode and | |
| 692 // packetize+transmit the RTP packet. When |number_of_voe_channels| == 0, | |
| 693 // do the operations on all the existing VoE channels; otherwise the | |
| 694 // operations will be done on specific channels. | |
| 695 if (number_of_voe_channels == 0) { | |
| 696 shared_->transmit_mixer()->DemuxAndMix(); | |
| 697 shared_->transmit_mixer()->EncodeAndSend(); | |
| 698 } else { | |
| 699 shared_->transmit_mixer()->DemuxAndMix(voe_channels, | |
| 700 number_of_voe_channels); | |
| 701 shared_->transmit_mixer()->EncodeAndSend(voe_channels, | |
| 702 number_of_voe_channels); | |
| 703 } | |
| 704 | |
| 705 // Scale from VoE to ADM level range. | |
| 706 uint32_t new_voe_mic_level = shared_->transmit_mixer()->CaptureLevel(); | |
| 707 if (new_voe_mic_level != voe_mic_level) { | |
| 708 // Return the new volume if AGC has changed the volume. | |
| 709 return static_cast<int>((new_voe_mic_level * max_volume + | |
| 710 static_cast<int>(kMaxVolumeLevel / 2)) / | |
| 711 kMaxVolumeLevel); | |
| 712 } | |
| 713 | |
| 714 // Return 0 to indicate no change on the volume. | |
| 715 return 0; | |
| 716 } | |
| 717 | |
| 718 void VoEBaseImpl::GetPlayoutData(int sample_rate, size_t number_of_channels, | 697 void VoEBaseImpl::GetPlayoutData(int sample_rate, size_t number_of_channels, |
| 719 size_t number_of_frames, bool feed_data_to_apm, | 698 size_t number_of_frames, bool feed_data_to_apm, |
| 720 void* audio_data, int64_t* elapsed_time_ms, | 699 void* audio_data, int64_t* elapsed_time_ms, |
| 721 int64_t* ntp_time_ms) { | 700 int64_t* ntp_time_ms) { |
| 722 assert(shared_->output_mixer() != nullptr); | 701 assert(shared_->output_mixer() != nullptr); |
| 723 | 702 |
| 724 // TODO(andrew): if the device is running in mono, we should tell the mixer | 703 // TODO(andrew): if the device is running in mono, we should tell the mixer |
| 725 // here so that it will only request mono from AudioCodingModule. | 704 // here so that it will only request mono from AudioCodingModule. |
| 726 // Perform mixing of all active participants (channel-based mixing) | 705 // Perform mixing of all active participants (channel-based mixing) |
| 727 shared_->output_mixer()->MixActiveChannels(); | 706 shared_->output_mixer()->MixActiveChannels(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 746 shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, |
| 768 "AssociateSendChannel() failed to locate accociate_send_channel"); | 747 "AssociateSendChannel() failed to locate accociate_send_channel"); |
| 769 return -1; | 748 return -1; |
| 770 } | 749 } |
| 771 | 750 |
| 772 channel_ptr->set_associate_send_channel(ch); | 751 channel_ptr->set_associate_send_channel(ch); |
| 773 return 0; | 752 return 0; |
| 774 } | 753 } |
| 775 | 754 |
| 776 } // namespace webrtc | 755 } // namespace webrtc |
| OLD | NEW |