diff options
author | Roxie Linden <roxie@lindenlab.com> | 2023-09-18 11:25:47 -0700 |
---|---|---|
committer | Roxie Linden <roxie@lindenlab.com> | 2024-02-22 23:11:34 -0800 |
commit | 639e63faab239b88d41c8e2c755509e9dcdc6251 (patch) | |
tree | b2b2afcf4abd406be6c43d32c172e380aa2d2c86 | |
parent | b1906593003b82fb8b442540e4ec69101f2c17c3 (diff) |
Fix voice device settings
-rw-r--r-- | indra/llwebrtc/llwebrtc.cpp | 94 | ||||
-rw-r--r-- | indra/llwebrtc/llwebrtc_impl.h | 3 | ||||
-rw-r--r-- | indra/newview/llpanelvoicedevicesettings.cpp | 79 |
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() |