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() | 
