summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoxie Linden <roxie@lindenlab.com>2023-09-18 11:25:47 -0700
committerRoxie Linden <roxie@lindenlab.com>2024-02-22 23:11:34 -0800
commit639e63faab239b88d41c8e2c755509e9dcdc6251 (patch)
treeb2b2afcf4abd406be6c43d32c172e380aa2d2c86
parentb1906593003b82fb8b442540e4ec69101f2c17c3 (diff)
Fix voice device settings
-rw-r--r--indra/llwebrtc/llwebrtc.cpp94
-rw-r--r--indra/llwebrtc/llwebrtc_impl.h3
-rw-r--r--indra/newview/llpanelvoicedevicesettings.cpp79
3 files changed, 120 insertions, 56 deletions
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index edf941436e..96be2c1f0b 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -55,7 +55,7 @@ void LLWebRTCImpl::init()
mSignalingThread->SetName("WebRTCSignalingThread", nullptr);
mSignalingThread->Start();
- mSignalingThread->PostTask(
+ mWorkerThread->PostTask(
[this]()
{
mDeviceModule = webrtc::CreateAudioDeviceWithDataObserver(webrtc::AudioDeviceModule::AudioLayer::kPlatformDefaultAudio,
@@ -68,7 +68,7 @@ void LLWebRTCImpl::init()
void LLWebRTCImpl::refreshDevices()
{
- mSignalingThread->PostTask([this]() { updateDevices(); });
+ mWorkerThread->PostTask([this]() { updateDevices(); });
}
void LLWebRTCImpl::setDevicesObserver(LLWebRTCDevicesObserver *observer) { mVoiceDevicesObserverList.emplace_back(observer); }
@@ -85,41 +85,48 @@ void LLWebRTCImpl::unsetDevicesObserver(LLWebRTCDevicesObserver *observer)
void LLWebRTCImpl::setCaptureDevice(const std::string &id)
{
- mSignalingThread->PostTask(
+ mWorkerThread->PostTask(
[this, id]()
{
+ mDeviceModule->StopRecording();
int16_t captureDeviceCount = mDeviceModule->RecordingDevices();
for (int16_t index = 0; index < captureDeviceCount; index++)
{
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
mDeviceModule->RecordingDeviceName(index, name, guid);
- if (id == guid || id == name)
+ if (id == guid || id == "Default")
{
+ RTC_LOG(LS_INFO) << __FUNCTION__ << "Set recording device to " << name << " " << guid << " " << index;
mDeviceModule->SetRecordingDevice(index);
break;
}
}
+ mDeviceModule->InitRecording();
+ mDeviceModule->StartRecording();
});
}
void LLWebRTCImpl::setRenderDevice(const std::string &id)
{
- mSignalingThread->PostTask(
+ mWorkerThread->PostTask(
[this, id]()
{
+ mDeviceModule->StopPlayout();
int16_t renderDeviceCount = mDeviceModule->RecordingDevices();
for (int16_t index = 0; index < renderDeviceCount; index++)
{
char name[webrtc::kAdmMaxDeviceNameSize];
char guid[webrtc::kAdmMaxGuidSize];
mDeviceModule->PlayoutDeviceName(index, name, guid);
- if (id == guid || id == name)
+ if (id == guid || id == "Default")
{
mDeviceModule->SetPlayoutDevice(index);
break;
}
}
+ mDeviceModule->InitPlayout();
+ mDeviceModule->StartPlayout();
});
}
@@ -156,7 +163,7 @@ void LLWebRTCImpl::updateDevices()
void LLWebRTCImpl::setTuningMode(bool enable)
{
- mSignalingThread->PostTask(
+ mWorkerThread->PostTask(
[this, enable]()
{
if (enable)
@@ -181,7 +188,7 @@ void LLWebRTCImpl::OnCaptureData(const void *audio_samples,
const size_t num_channels,
const uint32_t samples_per_sec)
{
- if (bytes_per_sample != 4)
+ if (bytes_per_sample != 2)
{
return;
}
@@ -220,28 +227,31 @@ void LLWebRTCImpl::unsetSignalingObserver(LLWebRTCSignalingObserver *observer)
}
}
+
bool LLWebRTCImpl::initializeConnection()
{
RTC_DCHECK(!mPeerConnection);
- RTC_DCHECK(!mPeerConnectionFactory);
+ RTC_DCHECK(mPeerConnectionFactory);
mAnswerReceived = false;
+
+ mSignalingThread->PostTask([this]() { initializeConnectionThreaded(); });
+ return true;
+}
+
+
+
+bool LLWebRTCImpl::initializeConnectionThreaded()
+{
mPeerConnectionFactory = webrtc::CreatePeerConnectionFactory(mNetworkThread.get(),
mWorkerThread.get(),
mSignalingThread.get(),
- nullptr /* default_adm */,
+ mDeviceModule,
webrtc::CreateBuiltinAudioEncoderFactory(),
webrtc::CreateBuiltinAudioDecoderFactory(),
nullptr /* video_encoder_factory */,
nullptr /* video_decoder_factory */,
nullptr /* audio_mixer */,
nullptr /* audio_processing */);
-
- if (!mPeerConnectionFactory)
- {
- shutdownConnection();
- return false;
- }
-
webrtc::PeerConnectionInterface::RTCConfiguration config;
config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
webrtc::PeerConnectionInterface::IceServer server;
@@ -272,16 +282,34 @@ bool LLWebRTCImpl::initializeConnection()
cricket::AudioOptions audioOptions;
audioOptions.auto_gain_control = true;
- audioOptions.echo_cancellation = true;
+ audioOptions.echo_cancellation = false; // incompatible with opus stereo
audioOptions.noise_suppression = true;
rtc::scoped_refptr<webrtc::MediaStreamInterface> stream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream");
rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
- mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(cricket::AudioOptions()).get()));
+ mPeerConnectionFactory->CreateAudioTrack("SLAudio", mPeerConnectionFactory->CreateAudioSource(audioOptions).get()));
audio_track->set_enabled(true);
stream->AddTrack(audio_track);
mPeerConnection->AddTrack(audio_track, {"SLStream"});
+
+ auto senders = mPeerConnection->GetSenders();
+
+ for (auto &sender : senders)
+ {
+ webrtc::RtpParameters params;
+ webrtc::RtpCodecParameters codecparam;
+ codecparam.name = "opus";
+ codecparam.kind = cricket::MEDIA_TYPE_AUDIO;
+ codecparam.clock_rate = 48000;
+ codecparam.num_channels = 1;
+ codecparam.parameters["stereo"] = "0";
+ codecparam.parameters["sprop-stereo"] = "0";
+
+ params.codecs.push_back(codecparam);
+ sender->SetParameters(params);
+ }
+
mPeerConnection->SetLocalDescription(rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface>(this));
RTC_LOG(LS_INFO) << __FUNCTION__ << " " << mPeerConnection->signaling_state();
@@ -297,6 +325,12 @@ void LLWebRTCImpl::shutdownConnection()
void LLWebRTCImpl::AnswerAvailable(const std::string &sdp)
{
+ std::istringstream sdp_stream(sdp);
+ std::string sdp_line;
+ while (std::getline(sdp_stream, sdp_line))
+ {
+ RTC_LOG(LS_INFO) << __FUNCTION__ << " Remote SDP: " << sdp_line;
+ }
mSignalingThread->PostTask(
[this, sdp]()
{
@@ -515,10 +549,28 @@ void LLWebRTCImpl::OnSetLocalDescriptionComplete(webrtc::RTCError error)
auto desc = mPeerConnection->pending_local_description();
std::string sdp;
desc->ToString(&sdp);
- RTC_LOG(LS_INFO) << __FUNCTION__ << " Local SDP: " << sdp;
+ // mangle the sdp as this is the only way currently to bump up
+ // the send audio rate to 48k
+ std::istringstream sdp_stream(sdp);
+ std::ostringstream sdp_mangled_stream;
+ std::string sdp_line;
+ while (std::getline(sdp_stream, sdp_line)) {
+ int bandwidth = 0;
+ int payload_id = 0;
+ RTC_LOG(LS_INFO) << __FUNCTION__ << " Local SDP: " << sdp_line;
+ // force mono
+ if (std::sscanf(sdp_line.c_str(), "a=rtpmap:%i opus/%i/2", &payload_id, &bandwidth) == 2)
+ {
+ sdp_mangled_stream << sdp_line << "\n";
+ }
+ else
+ {
+ sdp_mangled_stream << sdp_line << "\n";
+ }
+ }
for (auto &observer : mSignalingObserverList)
{
- observer->OnOfferAvailable(sdp);
+ observer->OnOfferAvailable(sdp_mangled_stream.str());
}
}
diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h
index 5c6cfcdbc6..3f9b06cae7 100644
--- a/indra/llwebrtc/llwebrtc_impl.h
+++ b/indra/llwebrtc/llwebrtc_impl.h
@@ -160,6 +160,9 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface,
void OnSetLocalDescriptionComplete(webrtc::RTCError error) override;
protected:
+
+ bool initializeConnectionThreaded();
+
std::unique_ptr<rtc::Thread> mNetworkThread;
std::unique_ptr<rtc::Thread> mWorkerThread;
std::unique_ptr<rtc::Thread> mSignalingThread;
diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp
index 28631e2b7b..48c90d6856 100644
--- a/indra/newview/llpanelvoicedevicesettings.cpp
+++ b/indra/newview/llpanelvoicedevicesettings.cpp
@@ -236,44 +236,47 @@ void LLPanelVoiceDeviceSettings::refresh()
if(mCtrlInputDevices)
{
- mCtrlInputDevices->removeall();
- mCtrlInputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
-
- for(device=LLVoiceClient::getInstance()->getCaptureDevices().begin();
- device != LLVoiceClient::getInstance()->getCaptureDevices().end();
- device++)
- {
- mCtrlInputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
- }
-
- // Fix invalid input audio device preference.
- if (!mCtrlInputDevices->setSelectedByValue(mInputDevice, TRUE))
- {
- mCtrlInputDevices->setValue(DEFAULT_DEVICE);
- gSavedSettings.setString("VoiceInputAudioDevice", DEFAULT_DEVICE);
- mInputDevice = DEFAULT_DEVICE;
- }
+ LLVoiceDeviceList devices = LLVoiceClient::getInstance()->getCaptureDevices();
+ if (devices.size() > 0) // if zero, we've not received our devices yet
+ {
+ mCtrlInputDevices->removeall();
+ mCtrlInputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
+ for (auto& device : devices)
+ {
+ mCtrlInputDevices->add(getLocalizedDeviceName(device.display_name), device.full_name, ADD_BOTTOM);
+ }
+
+ // Fix invalid input audio device preference.
+ if (!mCtrlInputDevices->setSelectedByValue(mInputDevice, TRUE))
+ {
+ mCtrlInputDevices->setValue(DEFAULT_DEVICE);
+ gSavedSettings.setString("VoiceInputAudioDevice", DEFAULT_DEVICE);
+ mInputDevice = DEFAULT_DEVICE;
+ }
+ }
}
if(mCtrlOutputDevices)
{
- mCtrlOutputDevices->removeall();
- mCtrlOutputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
-
- for(device = LLVoiceClient::getInstance()->getRenderDevices().begin();
- device != LLVoiceClient::getInstance()->getRenderDevices().end();
- device++)
- {
- mCtrlOutputDevices->add(getLocalizedDeviceName(device->display_name), device->full_name, ADD_BOTTOM);
- }
-
- // Fix invalid output audio device preference.
- if (!mCtrlOutputDevices->setSelectedByValue(mOutputDevice, TRUE))
- {
- mCtrlOutputDevices->setValue(DEFAULT_DEVICE);
- gSavedSettings.setString("VoiceOutputAudioDevice", DEFAULT_DEVICE);
- mOutputDevice = DEFAULT_DEVICE;
- }
+ LLVoiceDeviceList devices = LLVoiceClient::getInstance()->getRenderDevices();
+ if (devices.size() > 0) // if zero, we've not received our devices yet
+ {
+ mCtrlOutputDevices->removeall();
+ mCtrlOutputDevices->add(getLocalizedDeviceName(DEFAULT_DEVICE), DEFAULT_DEVICE, ADD_BOTTOM);
+
+ for (auto& device : devices)
+ {
+ mCtrlOutputDevices->add(getLocalizedDeviceName(device.display_name), device.full_name, ADD_BOTTOM);
+ }
+
+ // Fix invalid output audio device preference.
+ if (!mCtrlOutputDevices->setSelectedByValue(mOutputDevice, TRUE))
+ {
+ mCtrlOutputDevices->setValue(DEFAULT_DEVICE);
+ gSavedSettings.setString("VoiceOutputAudioDevice", DEFAULT_DEVICE);
+ mOutputDevice = DEFAULT_DEVICE;
+ }
+ }
}
}
}
@@ -316,8 +319,11 @@ void LLPanelVoiceDeviceSettings::onCommitInputDevice()
if(LLVoiceClient::getInstance())
{
mInputDevice = mCtrlInputDevices->getValue().asString();
- LLVoiceClient::getInstance()->setRenderDevice(mInputDevice);
+ LLVoiceClient::getInstance()->setCaptureDevice(mInputDevice);
}
+ // the preferences floater stuff is a mess, hence apply will never
+ // be called when 'ok' is pressed, so just force it for now.
+ apply();
}
void LLPanelVoiceDeviceSettings::onCommitOutputDevice()
@@ -328,6 +334,9 @@ void LLPanelVoiceDeviceSettings::onCommitOutputDevice()
mOutputDevice = mCtrlOutputDevices->getValue().asString();
LLVoiceClient::getInstance()->setRenderDevice(mOutputDevice);
}
+ // the preferences floater stuff is a mess, hence apply will never
+ // be called when 'ok' is pressed, so just force it for now.
+ apply();
}
void LLPanelVoiceDeviceSettings::onOutputDevicesClicked()