diff options
author | Roxie Linden <roxie@lindenlab.com> | 2023-09-22 16:55:13 -0700 |
---|---|---|
committer | Roxie Linden <roxie@lindenlab.com> | 2024-02-22 23:11:34 -0800 |
commit | 0110e37c7af96b02fd4ad92144b1b042e307d6a5 (patch) | |
tree | 300f0fe29863e55fb354a7d7796e5eccbd028a0b | |
parent | baf01e50cfc1d59c5853aad3948f6e741995ee62 (diff) |
Smooth voice power level reporting.
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 21 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 5 | ||||
-rw-r--r-- | indra/newview/llvoicewebrtc.cpp | 52 |
3 files changed, 58 insertions, 20 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index a3dadd696c..7b5ca7fb16 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -39,6 +39,7 @@ namespace llwebrtc const float VOLUME_SCALE_WEBRTC = 3.0f; +LLAudioDeviceObserver::LLAudioDeviceObserver() : mMicrophoneEnergy(0.0), mSumVector {0} {} double LLAudioDeviceObserver::getMicrophoneEnergy() { return mMicrophoneEnergy; } @@ -48,14 +49,26 @@ void LLAudioDeviceObserver::OnCaptureData(const void *audio_samples, const size_t num_channels, const uint32_t samples_per_sec) { - double energy = 0; + float energy = 0; const short *samples = (const short *) audio_samples; for (size_t index = 0; index < num_samples * num_channels; index++) { - double sample = (static_cast<double>(samples[index]) / (double) 32768); + float sample = (static_cast<float>(samples[index]) / (float) 32768); energy += sample * sample; } - mMicrophoneEnergy = std::sqrt(energy); + + // smooth it. + size_t buffer_size = sizeof(mSumVector) / sizeof(mSumVector[0]); + float totalSum = 0; + int i; + for (i = 0; i < (buffer_size - 1); i++) + { + mSumVector[i] = mSumVector[i + 1]; + totalSum += mSumVector[i]; + } + mSumVector[i] = energy; + totalSum += energy; + mMicrophoneEnergy = std::sqrt(totalSum / (num_samples * buffer_size)); } void LLAudioDeviceObserver::OnRenderData(const void *audio_samples, @@ -479,7 +492,7 @@ void LLWebRTCImpl::setSpeakerVolume(float volume) double LLWebRTCImpl::getAudioLevel() { - return mAudioDeviceObserver->getMicrophoneEnergy(); + return 20*mAudioDeviceObserver->getMicrophoneEnergy(); } // diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index da829e52af..70586f9013 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -66,6 +66,8 @@ namespace llwebrtc class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver { public: + LLAudioDeviceObserver(); + double getMicrophoneEnergy(); void OnCaptureData(const void *audio_samples, @@ -81,7 +83,8 @@ class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver const uint32_t samples_per_sec) override; protected: - double mMicrophoneEnergy; + float mSumVector[30]; // 300 ms of smoothing + float mMicrophoneEnergy; }; class LLWebRTCImpl : public LLWebRTCDeviceInterface, diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 3073a58183..c22246d841 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -87,6 +87,7 @@ namespace { const F32 VOLUME_SCALE_WEBRTC = 0.01f; const F32 SPEAKING_TIMEOUT = 1.f; + const F32 SPEAKING_AUDIO_LEVEL = 0.05; static const std::string VOICE_SERVER_TYPE = "WebRTC"; @@ -2366,16 +2367,28 @@ void LLWebRTCVoiceClient::sendPositionAndVolumeUpdate(void) if (mWebRTCDataInterface && mWebRTCAudioInterface) { - uint32_t audio_level = (uint32_t) ((F32) mWebRTCDeviceInterface->getAudioLevel() * 256); - if (audio_level != mAudioLevel) + F32 audio_level = 0.0; + + if (!mMuteMic) + { + audio_level = (F32) mWebRTCDeviceInterface->getAudioLevel(); + } + uint32_t uint_audio_level = (uint32_t) (audio_level * 256); + if (uint_audio_level != mAudioLevel) { Json::FastWriter writer; - Json::Value root; - root["p"] = (uint32_t) ((F32) mWebRTCDeviceInterface->getAudioLevel() * 256); + Json::Value root; + root["p"] = uint_audio_level; std::string json_data = writer.write(root); mWebRTCDataInterface->sendData(json_data, false); - mAudioLevel = audio_level; + mAudioLevel = uint_audio_level; + participantStatePtr_t participant = findParticipantByID(gAgentID); + if (participant) + { + participant->mPower = audio_level; + participant->mIsSpeaking = participant->mPower > SPEAKING_AUDIO_LEVEL; + } } } @@ -2677,10 +2690,12 @@ void LLWebRTCVoiceClient::OnDataReceived(const std::string& data, bool binary) { removeParticipantByID(agent_id); } - participant->mPower = (F32) (voice_data[participant_id].get("p", Json::Value(participant->mPower)).asInt()) / 256; + F32 energyRMS = (F32) (voice_data[participant_id].get("p", Json::Value(participant->mPower)).asInt()) / 256; + // convert to decibles + participant->mPower = energyRMS; /* WebRTC appears to have deprecated VAD, but it's still in the Audio Processing Module so maybe we can use it at some point when we actually process frames. */ - participant->mIsSpeaking = participant->mPower > 0.05; + participant->mIsSpeaking = participant->mPower > SPEAKING_AUDIO_LEVEL; } } } @@ -4446,10 +4461,16 @@ void LLWebRTCVoiceClient::leaveChannel(void) void LLWebRTCVoiceClient::setMuteMic(bool muted) { + participantStatePtr_t participant = findParticipantByID(gAgentID); + if (participant) + { + participant->mPower = 0.0; + } if (mWebRTCAudioInterface) { mWebRTCAudioInterface->setMute(muted); } + mMuteMic = muted; } void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled) @@ -4625,16 +4646,17 @@ BOOL LLWebRTCVoiceClient::getIsModeratorMuted(const LLUUID& id) return result; } -F32 LLWebRTCVoiceClient::getCurrentPower(const LLUUID& id) -{ - F32 result = 0; - participantStatePtr_t participant(findParticipantByID(id)); - if(participant) +F32 LLWebRTCVoiceClient::getCurrentPower(const LLUUID &id) +{ + F32 result = 0; + if (!mMuteMic) { - LL_WARNS("Voice") << "Power:" << participant->mPower << LL_ENDL; - result = participant->mPower*4; + participantStatePtr_t participant(findParticipantByID(id)); + if (participant) + { + result = participant->mPower * 4; + } } - return result; } |