summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoxie Linden <roxie@lindenlab.com>2023-09-22 16:55:13 -0700
committerRoxie Linden <roxie@lindenlab.com>2024-02-22 23:11:34 -0800
commit0110e37c7af96b02fd4ad92144b1b042e307d6a5 (patch)
tree300f0fe29863e55fb354a7d7796e5eccbd028a0b
parentbaf01e50cfc1d59c5853aad3948f6e741995ee62 (diff)
Smooth voice power level reporting.
-rw-r--r--indra/llwebrtc/llwebrtc.cpp21
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h5
-rw-r--r--indra/newview/llvoicewebrtc.cpp52
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;
}