Merge branch 'release/2025.07' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/skins/default/xui/en/menu_inventory.xmlmaster
commit
5fdef7863e
|
|
@ -42,7 +42,7 @@ jobs:
|
|||
needs: setup
|
||||
strategy:
|
||||
matrix:
|
||||
runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-2022","macos-15"]') }}
|
||||
runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-2022","macos-15-xlarge"]') }}
|
||||
configuration: ${{ fromJson(needs.setup.outputs.configurations) }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
outputs:
|
||||
|
|
@ -93,7 +93,6 @@ jobs:
|
|||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Checkout build variables
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -3030,11 +3030,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>6314fdcee81a3538a7d960178ade66301c2fa002</string>
|
||||
<string>43c5f93517794aeade550e4266b959d1f0cfcb7f</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.73-alpha/webrtc-m114.5735.08.73-alpha.11958809572-darwin64-11958809572.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-darwin64-17630578914.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3044,11 +3044,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>95d7730a3d6955697e043f3fdf20ebdcc0c71fc0</string>
|
||||
<string>efc5b176d878cfc16b8f82445d82ddb96815b6ab</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.73-alpha/webrtc-m114.5735.08.73-alpha.11958809572-linux64-11958809572.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-linux64-17630578914.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -3058,11 +3058,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>c7b329d6409576af6eb5b80655b007f52639c43b</string>
|
||||
<string>1e36f100de32c7c71325497a672fb1659b3f206d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.73-alpha/webrtc-m114.5735.08.73-alpha.11958809572-windows64-11958809572.tar.zst</string>
|
||||
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-windows64-17630578914.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -3075,7 +3075,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>copyright</key>
|
||||
<string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
|
||||
<key>version</key>
|
||||
<string>m114.5735.08.73-alpha.11958809572</string>
|
||||
<string>m137.7151.04.20-universal.17630578914</string>
|
||||
<key>name</key>
|
||||
<string>webrtc</string>
|
||||
<key>vcs_branch</key>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ if (WINDOWS)
|
|||
iphlpapi
|
||||
libcmt)
|
||||
# as the webrtc libraries are release, build this binary as release as well.
|
||||
target_compile_options(llwebrtc PRIVATE "/MT")
|
||||
target_compile_options(llwebrtc PRIVATE "/MT" "/Zc:wchar_t")
|
||||
if (USE_BUGSPLAT)
|
||||
set_target_properties(llwebrtc PROPERTIES PDB_OUTPUT_DIRECTORY "${SYMBOLS_STAGING_DIR}")
|
||||
endif (USE_BUGSPLAT)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -159,7 +159,10 @@ class LLWebRTCDeviceInterface
|
|||
virtual void setTuningMode(bool enable) = 0;
|
||||
virtual float getTuningAudioLevel() = 0; // for use during tuning
|
||||
virtual float getPeerConnectionAudioLevel() = 0; // for use when not tuning
|
||||
virtual void setPeerConnectionGain(float gain) = 0;
|
||||
virtual void setMicGain(float gain) = 0;
|
||||
virtual void setTuningMicGain(float gain) = 0;
|
||||
|
||||
virtual void setMute(bool mute, int delay_ms = 0) = 0;
|
||||
};
|
||||
|
||||
// LLWebRTCAudioInterface provides the viewer with a way
|
||||
|
|
|
|||
|
|
@ -54,12 +54,12 @@
|
|||
#include "rtc_base/ref_counted_object.h"
|
||||
#include "rtc_base/ssl_adapter.h"
|
||||
#include "rtc_base/thread.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "api/create_peerconnection_factory.h"
|
||||
#include "modules/audio_device/include/audio_device.h"
|
||||
#include "modules/audio_device/include/audio_device_data_observer.h"
|
||||
#include "rtc_base/task_queue.h"
|
||||
#include "api/task_queue/task_queue_factory.h"
|
||||
#include "api/task_queue/default_task_queue_factory.h"
|
||||
#include "modules/audio_device/include/audio_device_defines.h"
|
||||
|
|
@ -69,35 +69,30 @@ namespace llwebrtc
|
|||
|
||||
class LLWebRTCPeerConnectionImpl;
|
||||
|
||||
class LLWebRTCLogSink : public rtc::LogSink {
|
||||
class LLWebRTCLogSink : public webrtc::LogSink
|
||||
{
|
||||
public:
|
||||
LLWebRTCLogSink(LLWebRTCLogCallback* callback) :
|
||||
mCallback(callback)
|
||||
{
|
||||
}
|
||||
LLWebRTCLogSink(LLWebRTCLogCallback* callback) : mCallback(callback) {}
|
||||
|
||||
// Destructor: close the log file
|
||||
~LLWebRTCLogSink() override
|
||||
{
|
||||
}
|
||||
~LLWebRTCLogSink() override {}
|
||||
|
||||
void OnLogMessage(const std::string& msg,
|
||||
rtc::LoggingSeverity severity) override
|
||||
void OnLogMessage(const std::string& msg, webrtc::LoggingSeverity severity) override
|
||||
{
|
||||
if (mCallback)
|
||||
{
|
||||
switch(severity)
|
||||
switch (severity)
|
||||
{
|
||||
case rtc::LS_VERBOSE:
|
||||
case webrtc::LS_VERBOSE:
|
||||
mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg);
|
||||
break;
|
||||
case rtc::LS_INFO:
|
||||
case webrtc::LS_INFO:
|
||||
mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg);
|
||||
break;
|
||||
case rtc::LS_WARNING:
|
||||
case webrtc::LS_WARNING:
|
||||
mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg);
|
||||
break;
|
||||
case rtc::LS_ERROR:
|
||||
case webrtc::LS_ERROR:
|
||||
mCallback->LogMessage(LLWebRTCLogCallback::LOG_LEVEL_VERBOSE, msg);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -118,73 +113,307 @@ private:
|
|||
LLWebRTCLogCallback* mCallback;
|
||||
};
|
||||
|
||||
// Implements a class allowing capture of audio data
|
||||
// to determine audio level of the microphone.
|
||||
class LLAudioDeviceObserver : public webrtc::AudioDeviceDataObserver
|
||||
// -----------------------------------------------------------------------------
|
||||
// A proxy transport that forwards capture data to two AudioTransport sinks:
|
||||
// - the "engine" (libwebrtc's VoiceEngine)
|
||||
// - the "user" (your app's listener)
|
||||
//
|
||||
// Playout (NeedMorePlayData) goes only to the engine by default to avoid
|
||||
// double-writing into the output buffer. See notes below if you want a tap.
|
||||
// -----------------------------------------------------------------------------
|
||||
class LLWebRTCAudioTransport : public webrtc::AudioTransport
|
||||
{
|
||||
public:
|
||||
LLAudioDeviceObserver();
|
||||
public:
|
||||
LLWebRTCAudioTransport();
|
||||
|
||||
// Retrieve the RMS audio loudness
|
||||
float getMicrophoneEnergy();
|
||||
void SetEngineTransport(webrtc::AudioTransport* t);
|
||||
|
||||
// Data retrieved from the caputure device is
|
||||
// passed in here for processing.
|
||||
void OnCaptureData(const void *audio_samples,
|
||||
const size_t num_samples,
|
||||
const size_t bytes_per_sample,
|
||||
const size_t num_channels,
|
||||
const uint32_t samples_per_sec) override;
|
||||
// -------- Capture path: fan out to both sinks --------
|
||||
int32_t RecordedDataIsAvailable(const void* audio_data,
|
||||
size_t number_of_samples,
|
||||
size_t bytes_per_sample,
|
||||
size_t number_of_channels,
|
||||
uint32_t samples_per_sec,
|
||||
uint32_t total_delay_ms,
|
||||
int32_t clock_drift,
|
||||
uint32_t current_mic_level,
|
||||
bool key_pressed,
|
||||
uint32_t& new_mic_level) override;
|
||||
|
||||
// This is for data destined for the render device.
|
||||
// not currently used.
|
||||
void OnRenderData(const void *audio_samples,
|
||||
const size_t num_samples,
|
||||
const size_t bytes_per_sample,
|
||||
const size_t num_channels,
|
||||
const uint32_t samples_per_sec) override;
|
||||
// -------- Playout path: delegate to engine only --------
|
||||
int32_t NeedMorePlayData(size_t number_of_samples,
|
||||
size_t bytes_per_sample,
|
||||
size_t number_of_channels,
|
||||
uint32_t samples_per_sec,
|
||||
void* audio_data,
|
||||
size_t& number_of_samples_out,
|
||||
int64_t* elapsed_time_ms,
|
||||
int64_t* ntp_time_ms) override;
|
||||
|
||||
// Method to pull mixed render audio data from all active VoE channels.
|
||||
// The data will not be passed as reference for audio processing internally.
|
||||
void PullRenderData(int bits_per_sample,
|
||||
int sample_rate,
|
||||
size_t number_of_channels,
|
||||
size_t number_of_frames,
|
||||
void* audio_data,
|
||||
int64_t* elapsed_time_ms,
|
||||
int64_t* ntp_time_ms) override;
|
||||
|
||||
float GetMicrophoneEnergy() { return mMicrophoneEnergy.load(std::memory_order_relaxed); }
|
||||
void SetGain(float gain) { mGain.store(gain, std::memory_order_relaxed); }
|
||||
|
||||
private:
|
||||
std::atomic<webrtc::AudioTransport*> engine_{ nullptr };
|
||||
static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing (30 frames)
|
||||
float mSumVector[NUM_PACKETS_TO_FILTER];
|
||||
std::atomic<float> mMicrophoneEnergy;
|
||||
std::atomic<float> mGain{ 0.0f };
|
||||
|
||||
protected:
|
||||
static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing (30 frames)
|
||||
float mSumVector[NUM_PACKETS_TO_FILTER];
|
||||
float mMicrophoneEnergy;
|
||||
};
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// LLWebRTCAudioDeviceModule
|
||||
// - Wraps a real ADM to provide microphone energy for tuning
|
||||
// -----------------------------------------------------------------------------
|
||||
class LLWebRTCAudioDeviceModule : public webrtc::AudioDeviceModule
|
||||
{
|
||||
public:
|
||||
explicit LLWebRTCAudioDeviceModule(webrtc::scoped_refptr<webrtc::AudioDeviceModule> inner) : inner_(std::move(inner)), tuning_(false)
|
||||
{
|
||||
RTC_CHECK(inner_);
|
||||
}
|
||||
|
||||
// ----- AudioDeviceModule interface: we mostly forward to |inner_| -----
|
||||
int32_t ActiveAudioLayer(AudioLayer* audioLayer) const override { return inner_->ActiveAudioLayer(audioLayer); }
|
||||
|
||||
int32_t RegisterAudioCallback(webrtc::AudioTransport* engine_transport) override
|
||||
{
|
||||
// The engine registers its transport here. We put our audio transport between engine and ADM.
|
||||
audio_transport_.SetEngineTransport(engine_transport);
|
||||
// Register our proxy with the real ADM.
|
||||
return inner_->RegisterAudioCallback(&audio_transport_);
|
||||
}
|
||||
|
||||
int32_t Init() override { return inner_->Init(); }
|
||||
int32_t Terminate() override { return inner_->Terminate(); }
|
||||
bool Initialized() const override { return inner_->Initialized(); }
|
||||
|
||||
// --- Device enumeration/selection (forward) ---
|
||||
int16_t PlayoutDevices() override { return inner_->PlayoutDevices(); }
|
||||
int16_t RecordingDevices() override { return inner_->RecordingDevices(); }
|
||||
int32_t PlayoutDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override
|
||||
{
|
||||
return inner_->PlayoutDeviceName(index, name, guid);
|
||||
}
|
||||
int32_t RecordingDeviceName(uint16_t index, char name[webrtc::kAdmMaxDeviceNameSize], char guid[webrtc::kAdmMaxGuidSize]) override
|
||||
{
|
||||
return inner_->RecordingDeviceName(index, name, guid);
|
||||
}
|
||||
int32_t SetPlayoutDevice(uint16_t index) override { return inner_->SetPlayoutDevice(index); }
|
||||
int32_t SetRecordingDevice(uint16_t index) override { return inner_->SetRecordingDevice(index); }
|
||||
|
||||
// Windows default/communications selectors, if your branch exposes them:
|
||||
int32_t SetPlayoutDevice(WindowsDeviceType type) override { return inner_->SetPlayoutDevice(type); }
|
||||
int32_t SetRecordingDevice(WindowsDeviceType type) override { return inner_->SetRecordingDevice(type); }
|
||||
|
||||
// --- Init/start/stop (forward) ---
|
||||
int32_t InitPlayout() override { return inner_->InitPlayout(); }
|
||||
bool PlayoutIsInitialized() const override { return inner_->PlayoutIsInitialized(); }
|
||||
int32_t StartPlayout() override {
|
||||
if (tuning_) return 0; // For tuning, don't allow playout
|
||||
return inner_->StartPlayout();
|
||||
}
|
||||
int32_t StopPlayout() override { return inner_->StopPlayout(); }
|
||||
bool Playing() const override { return inner_->Playing(); }
|
||||
|
||||
int32_t InitRecording() override { return inner_->InitRecording(); }
|
||||
bool RecordingIsInitialized() const override { return inner_->RecordingIsInitialized(); }
|
||||
int32_t StartRecording() override {
|
||||
// ignore start recording as webrtc.lib will
|
||||
// send one when streams first connect, resulting
|
||||
// in an inadvertant 'recording' when mute is on.
|
||||
// We take full control of StartRecording via
|
||||
// ForceStartRecording below.
|
||||
return 0;
|
||||
}
|
||||
int32_t StopRecording() override {
|
||||
if (tuning_) return 0; // if we're tuning, disregard the StopRecording we get from disabling the streams
|
||||
return inner_->StopRecording();
|
||||
}
|
||||
int32_t ForceStartRecording() { return inner_->StartRecording(); }
|
||||
int32_t ForceStopRecording() { return inner_->StopRecording(); }
|
||||
bool Recording() const override { return inner_->Recording(); }
|
||||
|
||||
// --- Stereo opts (forward if available on your branch) ---
|
||||
int32_t SetStereoPlayout(bool enable) override { return inner_->SetStereoPlayout(enable); }
|
||||
int32_t SetStereoRecording(bool enable) override { return inner_->SetStereoRecording(enable); }
|
||||
int32_t PlayoutIsAvailable(bool* available) override { return inner_->PlayoutIsAvailable(available); }
|
||||
int32_t RecordingIsAvailable(bool* available) override { return inner_->RecordingIsAvailable(available); }
|
||||
|
||||
// --- AGC/Volume/Mute/etc. (forward) ---
|
||||
int32_t SetMicrophoneVolume(uint32_t volume) override { return inner_->SetMicrophoneVolume(volume); }
|
||||
int32_t MicrophoneVolume(uint32_t* volume) const override { return inner_->MicrophoneVolume(volume); }
|
||||
|
||||
// --- Speaker/Microphone init (forward) ---
|
||||
int32_t InitSpeaker() override { return inner_->InitSpeaker(); }
|
||||
bool SpeakerIsInitialized() const override { return inner_->SpeakerIsInitialized(); }
|
||||
int32_t InitMicrophone() override { return inner_->InitMicrophone(); }
|
||||
bool MicrophoneIsInitialized() const override { return inner_->MicrophoneIsInitialized(); }
|
||||
|
||||
// --- Speaker Volume (forward) ---
|
||||
int32_t SpeakerVolumeIsAvailable(bool* available) override { return inner_->SpeakerVolumeIsAvailable(available); }
|
||||
int32_t SetSpeakerVolume(uint32_t volume) override { return inner_->SetSpeakerVolume(volume); }
|
||||
int32_t SpeakerVolume(uint32_t* volume) const override { return inner_->SpeakerVolume(volume); }
|
||||
int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override { return inner_->MaxSpeakerVolume(maxVolume); }
|
||||
int32_t MinSpeakerVolume(uint32_t* minVolume) const override { return inner_->MinSpeakerVolume(minVolume); }
|
||||
|
||||
// --- Microphone Volume (forward) ---
|
||||
int32_t MicrophoneVolumeIsAvailable(bool* available) override { return inner_->MicrophoneVolumeIsAvailable(available); }
|
||||
int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { return inner_->MaxMicrophoneVolume(maxVolume); }
|
||||
int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { return inner_->MinMicrophoneVolume(minVolume); }
|
||||
|
||||
// --- Speaker Mute (forward) ---
|
||||
int32_t SpeakerMuteIsAvailable(bool* available) override { return inner_->SpeakerMuteIsAvailable(available); }
|
||||
int32_t SetSpeakerMute(bool enable) override { return inner_->SetSpeakerMute(enable); }
|
||||
int32_t SpeakerMute(bool* enabled) const override { return inner_->SpeakerMute(enabled); }
|
||||
|
||||
// --- Microphone Mute (forward) ---
|
||||
int32_t MicrophoneMuteIsAvailable(bool* available) override { return inner_->MicrophoneMuteIsAvailable(available); }
|
||||
int32_t SetMicrophoneMute(bool enable) override { return inner_->SetMicrophoneMute(enable); }
|
||||
int32_t MicrophoneMute(bool* enabled) const override { return inner_->MicrophoneMute(enabled); }
|
||||
|
||||
// --- Stereo Support (forward) ---
|
||||
int32_t StereoPlayoutIsAvailable(bool* available) const override { return inner_->StereoPlayoutIsAvailable(available); }
|
||||
int32_t StereoPlayout(bool* enabled) const override { return inner_->StereoPlayout(enabled); }
|
||||
int32_t StereoRecordingIsAvailable(bool* available) const override { return inner_->StereoRecordingIsAvailable(available); }
|
||||
int32_t StereoRecording(bool* enabled) const override { return inner_->StereoRecording(enabled); }
|
||||
|
||||
// --- Delay/Timing (forward) ---
|
||||
int32_t PlayoutDelay(uint16_t* delayMS) const override { return inner_->PlayoutDelay(delayMS); }
|
||||
|
||||
// --- Built-in Audio Processing (forward) ---
|
||||
bool BuiltInAECIsAvailable() const override { return inner_->BuiltInAECIsAvailable(); }
|
||||
bool BuiltInAGCIsAvailable() const override { return inner_->BuiltInAGCIsAvailable(); }
|
||||
bool BuiltInNSIsAvailable() const override { return inner_->BuiltInNSIsAvailable(); }
|
||||
int32_t EnableBuiltInAEC(bool enable) override { return inner_->EnableBuiltInAEC(enable); }
|
||||
int32_t EnableBuiltInAGC(bool enable) override { return inner_->EnableBuiltInAGC(enable); }
|
||||
int32_t EnableBuiltInNS(bool enable) override { return inner_->EnableBuiltInNS(enable); }
|
||||
|
||||
// --- Additional AudioDeviceModule methods (forward) ---
|
||||
int32_t GetPlayoutUnderrunCount() const override { return inner_->GetPlayoutUnderrunCount(); }
|
||||
|
||||
// Used to generate RTC stats. If not implemented, RTCAudioPlayoutStats will
|
||||
// not be present in the stats.
|
||||
std::optional<Stats> GetStats() const override { return inner_->GetStats(); }
|
||||
|
||||
// Only supported on iOS.
|
||||
#if defined(WEBRTC_IOS)
|
||||
virtual int GetPlayoutAudioParameters(AudioParameters* params) const override { return inner_->GetPlayoutAudioParameters(params); }
|
||||
virtual int GetRecordAudioParameters(AudioParameters* params) override { return inner_->GetRecordAudioParameters(params); }
|
||||
#endif // WEBRTC_IOS
|
||||
|
||||
virtual int32_t GetPlayoutDevice() const override { return inner_->GetPlayoutDevice(); }
|
||||
virtual int32_t GetRecordingDevice() const override { return inner_->GetRecordingDevice(); }
|
||||
virtual int32_t SetObserver(webrtc::AudioDeviceObserver* observer) override { return inner_->SetObserver(observer); }
|
||||
|
||||
// tuning microphone energy calculations
|
||||
float GetMicrophoneEnergy() { return audio_transport_.GetMicrophoneEnergy(); }
|
||||
void SetTuningMicGain(float gain) { audio_transport_.SetGain(gain); }
|
||||
void SetTuning(bool tuning, bool mute)
|
||||
{
|
||||
tuning_ = tuning;
|
||||
if (tuning)
|
||||
{
|
||||
inner_->InitRecording();
|
||||
inner_->StartRecording();
|
||||
inner_->StopPlayout();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mute)
|
||||
{
|
||||
inner_->StopRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
inner_->InitRecording();
|
||||
inner_->StartRecording();
|
||||
}
|
||||
inner_->StartPlayout();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
~LLWebRTCAudioDeviceModule() override = default;
|
||||
|
||||
private:
|
||||
webrtc::scoped_refptr<webrtc::AudioDeviceModule> inner_;
|
||||
LLWebRTCAudioTransport audio_transport_;
|
||||
|
||||
bool tuning_;
|
||||
};
|
||||
|
||||
class LLCustomProcessorState
|
||||
{
|
||||
|
||||
public:
|
||||
float getMicrophoneEnergy() { return mMicrophoneEnergy.load(std::memory_order_relaxed); }
|
||||
void setMicrophoneEnergy(float energy) { mMicrophoneEnergy.store(energy, std::memory_order_relaxed); }
|
||||
|
||||
void setGain(float gain)
|
||||
{
|
||||
mGain.store(gain, std::memory_order_relaxed);
|
||||
mDirty.store(true, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
float getGain() { return mGain.load(std::memory_order_relaxed); }
|
||||
|
||||
bool getDirty() { return mDirty.exchange(false, std::memory_order_relaxed); }
|
||||
|
||||
protected:
|
||||
std::atomic<bool> mDirty{ true };
|
||||
std::atomic<float> mMicrophoneEnergy{ 0.0f };
|
||||
std::atomic<float> mGain{ 0.0f };
|
||||
};
|
||||
|
||||
using LLCustomProcessorStatePtr = std::shared_ptr<LLCustomProcessorState>;
|
||||
|
||||
// Used to process/retrieve audio levels after
|
||||
// all of the processing (AGC, AEC, etc.) for display in-world to the user.
|
||||
class LLCustomProcessor : public webrtc::CustomProcessing
|
||||
{
|
||||
public:
|
||||
LLCustomProcessor();
|
||||
public:
|
||||
LLCustomProcessor(LLCustomProcessorStatePtr state);
|
||||
~LLCustomProcessor() override {}
|
||||
|
||||
// (Re-) Initializes the submodule.
|
||||
void Initialize(int sample_rate_hz, int num_channels) override;
|
||||
|
||||
// Analyzes the given capture or render signal.
|
||||
void Process(webrtc::AudioBuffer *audio) override;
|
||||
void Process(webrtc::AudioBuffer* audio) override;
|
||||
|
||||
// Returns a string representation of the module state.
|
||||
std::string ToString() const override { return ""; }
|
||||
|
||||
float getMicrophoneEnergy() { return mMicrophoneEnergy; }
|
||||
|
||||
void setGain(float gain) { mGain = gain; }
|
||||
|
||||
protected:
|
||||
static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing
|
||||
int mSampleRateHz;
|
||||
int mNumChannels;
|
||||
protected:
|
||||
static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing
|
||||
int mSampleRateHz{ 48000 };
|
||||
int mNumChannels{ 2 };
|
||||
int mRampFrames{ 2 };
|
||||
float mCurrentGain{ 0.0f };
|
||||
float mGainStep{ 0.0f };
|
||||
|
||||
float mSumVector[NUM_PACKETS_TO_FILTER];
|
||||
float mMicrophoneEnergy;
|
||||
float mGain;
|
||||
friend LLCustomProcessorState;
|
||||
LLCustomProcessorStatePtr mState;
|
||||
};
|
||||
|
||||
|
||||
// Primary singleton implementation for interfacing
|
||||
// with the native webrtc library.
|
||||
class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceSink
|
||||
class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceObserver
|
||||
{
|
||||
public:
|
||||
LLWebRTCImpl(LLWebRTCLogCallback* logCallback);
|
||||
|
|
@ -214,10 +443,15 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
|
|||
float getTuningAudioLevel() override;
|
||||
float getPeerConnectionAudioLevel() override;
|
||||
|
||||
void setPeerConnectionGain(float gain) override;
|
||||
void setMicGain(float gain) override;
|
||||
void setTuningMicGain(float gain) override;
|
||||
|
||||
void setMute(bool mute, int delay_ms = 20) override;
|
||||
|
||||
void intSetMute(bool mute, int delay_ms = 20);
|
||||
|
||||
//
|
||||
// AudioDeviceSink
|
||||
// AudioDeviceObserver
|
||||
//
|
||||
void OnDevicesUpdated() override;
|
||||
|
||||
|
|
@ -246,19 +480,19 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
|
|||
mNetworkThread->PostTask(std::move(task), location);
|
||||
}
|
||||
|
||||
void WorkerBlockingCall(rtc::FunctionView<void()> functor,
|
||||
void WorkerBlockingCall(webrtc::FunctionView<void()> functor,
|
||||
const webrtc::Location& location = webrtc::Location::Current())
|
||||
{
|
||||
mWorkerThread->BlockingCall(std::move(functor), location);
|
||||
}
|
||||
|
||||
void SignalingBlockingCall(rtc::FunctionView<void()> functor,
|
||||
void SignalingBlockingCall(webrtc::FunctionView<void()> functor,
|
||||
const webrtc::Location& location = webrtc::Location::Current())
|
||||
{
|
||||
mSignalingThread->BlockingCall(std::move(functor), location);
|
||||
}
|
||||
|
||||
void NetworkBlockingCall(rtc::FunctionView<void()> functor,
|
||||
void NetworkBlockingCall(webrtc::FunctionView<void()> functor,
|
||||
const webrtc::Location& location = webrtc::Location::Current())
|
||||
{
|
||||
mNetworkThread->BlockingCall(std::move(functor), location);
|
||||
|
|
@ -266,7 +500,7 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
|
|||
|
||||
// Allows the LLWebRTCPeerConnectionImpl class to retrieve the
|
||||
// native webrtc PeerConnectionFactory.
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> getPeerConnectionFactory()
|
||||
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> getPeerConnectionFactory()
|
||||
{
|
||||
return mPeerConnectionFactory;
|
||||
}
|
||||
|
|
@ -275,49 +509,47 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
|
|||
LLWebRTCPeerConnectionInterface* newPeerConnection();
|
||||
void freePeerConnection(LLWebRTCPeerConnectionInterface* peer_connection);
|
||||
|
||||
// enables/disables capture via the capture device
|
||||
void setRecording(bool recording);
|
||||
|
||||
void setPlayout(bool playing);
|
||||
|
||||
protected:
|
||||
|
||||
void workerDeployDevices();
|
||||
LLWebRTCLogSink* mLogSink;
|
||||
|
||||
// The native webrtc threads
|
||||
std::unique_ptr<rtc::Thread> mNetworkThread;
|
||||
std::unique_ptr<rtc::Thread> mWorkerThread;
|
||||
std::unique_ptr<rtc::Thread> mSignalingThread;
|
||||
std::unique_ptr<webrtc::Thread> mNetworkThread;
|
||||
std::unique_ptr<webrtc::Thread> mWorkerThread;
|
||||
std::unique_ptr<webrtc::Thread> mSignalingThread;
|
||||
|
||||
// The factory that allows creation of native webrtc PeerConnections.
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
|
||||
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
|
||||
|
||||
rtc::scoped_refptr<webrtc::AudioProcessing> mAudioProcessingModule;
|
||||
webrtc::scoped_refptr<webrtc::AudioProcessing> mAudioProcessingModule;
|
||||
|
||||
// more native webrtc stuff
|
||||
std::unique_ptr<webrtc::TaskQueueFactory> mTaskQueueFactory;
|
||||
std::unique_ptr<webrtc::TaskQueueFactory> mTaskQueueFactory;
|
||||
|
||||
|
||||
// Devices
|
||||
void updateDevices();
|
||||
rtc::scoped_refptr<webrtc::AudioDeviceModule> mTuningDeviceModule;
|
||||
rtc::scoped_refptr<webrtc::AudioDeviceModule> mPeerDeviceModule;
|
||||
void deployDevices();
|
||||
std::atomic<int> mDevicesDeploying;
|
||||
webrtc::scoped_refptr<LLWebRTCAudioDeviceModule> mDeviceModule;
|
||||
std::vector<LLWebRTCDevicesObserver *> mVoiceDevicesObserverList;
|
||||
|
||||
// accessors in native webrtc for devices aren't apparently implemented yet.
|
||||
bool mTuningMode;
|
||||
int32_t mRecordingDevice;
|
||||
std::string mRecordingDevice;
|
||||
LLWebRTCVoiceDeviceList mRecordingDeviceList;
|
||||
|
||||
int32_t mPlayoutDevice;
|
||||
std::string mPlayoutDevice;
|
||||
LLWebRTCVoiceDeviceList mPlayoutDeviceList;
|
||||
|
||||
bool mMute;
|
||||
float mGain;
|
||||
|
||||
LLAudioDeviceObserver * mTuningAudioDeviceObserver;
|
||||
LLCustomProcessor * mPeerCustomProcessor;
|
||||
LLCustomProcessorStatePtr mPeerCustomProcessor;
|
||||
|
||||
// peer connections
|
||||
std::vector<rtc::scoped_refptr<LLWebRTCPeerConnectionImpl>> mPeerConnections;
|
||||
std::vector<webrtc::scoped_refptr<LLWebRTCPeerConnectionImpl>> mPeerConnections;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -342,7 +574,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
|
|||
void terminate();
|
||||
|
||||
virtual void AddRef() const override = 0;
|
||||
virtual rtc::RefCountReleaseStatus Release() const override = 0;
|
||||
virtual webrtc::RefCountReleaseStatus Release() const override = 0;
|
||||
|
||||
//
|
||||
// LLWebRTCPeerConnection
|
||||
|
|
@ -373,10 +605,10 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
|
|||
//
|
||||
|
||||
void OnSignalingChange(webrtc::PeerConnectionInterface::SignalingState new_state) override {}
|
||||
void OnAddTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
|
||||
const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> &streams) override;
|
||||
void OnRemoveTrack(rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
|
||||
void OnDataChannel(rtc::scoped_refptr<webrtc::DataChannelInterface> channel) override;
|
||||
void OnAddTrack(webrtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
|
||||
const std::vector<webrtc::scoped_refptr<webrtc::MediaStreamInterface>> &streams) override;
|
||||
void OnRemoveTrack(webrtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
|
||||
void OnDataChannel(webrtc::scoped_refptr<webrtc::DataChannelInterface> channel) override;
|
||||
void OnRenegotiationNeeded() override {}
|
||||
void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState new_state) override {};
|
||||
void OnIceGatheringChange(webrtc::PeerConnectionInterface::IceGatheringState new_state) override;
|
||||
|
|
@ -415,7 +647,7 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
|
|||
|
||||
LLWebRTCImpl * mWebRTCImpl;
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
|
||||
webrtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory;
|
||||
|
||||
typedef enum {
|
||||
MUTE_INITIAL,
|
||||
|
|
@ -429,12 +661,12 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface,
|
|||
std::vector<std::unique_ptr<webrtc::IceCandidateInterface>> mCachedIceCandidates;
|
||||
bool mAnswerReceived;
|
||||
|
||||
rtc::scoped_refptr<webrtc::PeerConnectionInterface> mPeerConnection;
|
||||
rtc::scoped_refptr<webrtc::MediaStreamInterface> mLocalStream;
|
||||
webrtc::scoped_refptr<webrtc::PeerConnectionInterface> mPeerConnection;
|
||||
webrtc::scoped_refptr<webrtc::MediaStreamInterface> mLocalStream;
|
||||
|
||||
// data
|
||||
std::vector<LLWebRTCDataObserver *> mDataObserverList;
|
||||
rtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel;
|
||||
webrtc::scoped_refptr<webrtc::DataChannelInterface> mDataChannel;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
|
|||
{
|
||||
bool old_value = mIsInActiveVoiceChannel;
|
||||
mIsInActiveVoiceChannel = vmi->getUUID() == session_id;
|
||||
mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel);
|
||||
mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel && !LLVoiceChannel::isSuspended());
|
||||
if (old_value != mIsInActiveVoiceChannel)
|
||||
{
|
||||
refresh();
|
||||
|
|
|
|||
|
|
@ -4241,6 +4241,31 @@ void LLInventoryAction::fileUploadLocation(const LLUUID& dest_id, const std::str
|
|||
}
|
||||
}
|
||||
|
||||
bool LLInventoryAction::isFileUploadLocation(const LLUUID& dest_id, const std::string& action)
|
||||
{
|
||||
if (action == "def_model")
|
||||
{
|
||||
return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_OBJECT) == dest_id;
|
||||
}
|
||||
else if (action == "def_texture")
|
||||
{
|
||||
return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE) == dest_id;
|
||||
}
|
||||
else if (action == "def_sound")
|
||||
{
|
||||
return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_SOUND) == dest_id;
|
||||
}
|
||||
else if (action == "def_animation")
|
||||
{
|
||||
return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_ANIMATION) == dest_id;
|
||||
}
|
||||
else if (action == "def_pbr_material")
|
||||
{
|
||||
return gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL) == dest_id;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root)
|
||||
{
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
|
|
|
|||
|
|
@ -680,6 +680,7 @@ struct LLInventoryAction
|
|||
static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root);
|
||||
static void removeItemFromDND(LLFolderView* root);
|
||||
static void fileUploadLocation(const LLUUID& dest_id, const std::string& action);
|
||||
static bool isFileUploadLocation(const LLUUID& dest_id, const std::string& action);
|
||||
|
||||
static void saveMultipleTextures(const std::vector<std::string>& filenames, std::set<LLFolderViewItem*> selected_items, LLInventoryModel* model);
|
||||
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ LLContextMenu* LLInventoryGalleryContextMenu::createMenu()
|
|||
registrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, uuids, gFloaterView->getParentFloater(mGallery)));
|
||||
|
||||
enable_registrar.add("Inventory.CanSetUploadLocation", boost::bind(&LLInventoryGalleryContextMenu::canSetUploadLocation, this, _2));
|
||||
enable_registrar.add("Inventory.FileUploadLocation.Check", boost::bind(&LLInventoryGalleryContextMenu::isUploadLocationSelected, this, _2));
|
||||
|
||||
enable_registrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl*, const LLSD&)
|
||||
{
|
||||
|
|
@ -501,6 +502,12 @@ void LLInventoryGalleryContextMenu::fileUploadLocation(const LLSD& userdata)
|
|||
LLInventoryAction::fileUploadLocation(mUUIDs.front(), param);
|
||||
}
|
||||
|
||||
bool LLInventoryGalleryContextMenu::isUploadLocationSelected(const LLSD& userdata)
|
||||
{
|
||||
const std::string param = userdata.asString();
|
||||
return LLInventoryAction::isFileUploadLocation(mUUIDs.front(), param);
|
||||
}
|
||||
|
||||
bool LLInventoryGalleryContextMenu::canSetUploadLocation(const LLSD& userdata)
|
||||
{
|
||||
if (mUUIDs.size() != 1)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ protected:
|
|||
void updateMenuItemsVisibility(LLContextMenu* menu);
|
||||
|
||||
void fileUploadLocation(const LLSD& userdata);
|
||||
bool isUploadLocationSelected(const LLSD& userdata);
|
||||
bool canSetUploadLocation(const LLSD& userdata);
|
||||
|
||||
static void onRename(const LLSD& notification, const LLSD& response);
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
|
|||
mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
|
||||
mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this));
|
||||
mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2));
|
||||
mEnableCallbackRegistrar.add("Inventory.FileUploadLocation.Check", boost::bind(&LLInventoryPanel::isUploadLocationSelected, this, _2));
|
||||
mCommitCallbackRegistrar.add("Inventory.OpenNewFolderWindow", boost::bind(&LLInventoryPanel::openSingleViewInventory, this, LLUUID()));
|
||||
mCommitCallbackRegistrar.add("Inventory.CustomAction", boost::bind(&LLInventoryPanel::onCustomAction, this, _2)); // <FS:Ansariel> Prevent warning "No callback found for: 'Inventory.CustomAction' in control: Find Links"
|
||||
}
|
||||
|
|
@ -2032,6 +2033,13 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
|
|||
LLInventoryAction::fileUploadLocation(dest, param);
|
||||
}
|
||||
|
||||
bool LLInventoryPanel::isUploadLocationSelected(const LLSD& userdata)
|
||||
{
|
||||
const std::string param = userdata.asString();
|
||||
const LLUUID dest = LLFolderBridge::sSelf.get()->getUUID();
|
||||
return LLInventoryAction::isFileUploadLocation(dest, param);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id)
|
||||
{
|
||||
LLPanelMainInventory::newFolderWindow(folder_id.isNull() ? LLFolderBridge::sSelf.get()->getUUID() : folder_id);
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ public:
|
|||
void doCreate(const LLSD& userdata);
|
||||
bool beginIMSession();
|
||||
void fileUploadLocation(const LLSD& userdata);
|
||||
bool isUploadLocationSelected(const LLSD& userdata);
|
||||
void openSingleViewInventory(LLUUID folder_id = LLUUID());
|
||||
void purgeSelectedItems();
|
||||
bool attachObject(const LLSD& userdata);
|
||||
|
|
|
|||
|
|
@ -200,8 +200,17 @@ void SpeakingIndicatorManager::cleanupSingleton()
|
|||
|
||||
void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
|
||||
{
|
||||
switchSpeakerIndicators(mSwitchedIndicatorsOn, false);
|
||||
mSwitchedIndicatorsOn.clear();
|
||||
if (LLVoiceChannel::isSuspended())
|
||||
{
|
||||
switchSpeakerIndicators(mSwitchedIndicatorsOn, false);
|
||||
mSwitchedIndicatorsOn.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple onParticipantsChanged can arrive at the same time
|
||||
// from different sources, might want to filter by some factor.
|
||||
onParticipantsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SpeakingIndicatorManager::onParticipantsChanged()
|
||||
|
|
|
|||
|
|
@ -4286,13 +4286,10 @@ void send_agent_update(bool force_send, bool send_reliable)
|
|||
static F32 last_draw_disatance_step = 1024;
|
||||
F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance;
|
||||
|
||||
if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
|
||||
if (LLViewerTexture::isSystemMemoryCritical())
|
||||
{
|
||||
// If we are low on memory, reduce requested draw distance
|
||||
// Discard's bias is clamped to 4 so we need to check 2 to 4 range
|
||||
// Factor is intended to go from 1.0 to 2.0
|
||||
F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f;
|
||||
memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / factor, gAgentCamera.mDrawDistance / 2.f);
|
||||
memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / LLViewerTexture::getSystemMemoryBudgetFactor(), gAgentCamera.mDrawDistance / 2.f);
|
||||
}
|
||||
|
||||
if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)
|
||||
|
|
|
|||
|
|
@ -680,23 +680,35 @@ U32Megabytes LLViewerTexture::getFreeSystemMemory()
|
|||
return physical_res;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLViewerTexture::isSystemMemoryLow()
|
||||
S32Megabytes get_render_free_main_memory_treshold()
|
||||
{
|
||||
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
|
||||
const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
|
||||
return getFreeSystemMemory() < MIN_FREE_MAIN_MEMORY;
|
||||
return MIN_FREE_MAIN_MEMORY;
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLViewerTexture::isSystemMemoryLow()
|
||||
{
|
||||
return getFreeSystemMemory() < get_render_free_main_memory_treshold();
|
||||
}
|
||||
|
||||
//static
|
||||
bool LLViewerTexture::isSystemMemoryCritical()
|
||||
{
|
||||
return getFreeSystemMemory() < get_render_free_main_memory_treshold() / 2;
|
||||
}
|
||||
|
||||
F32 LLViewerTexture::getSystemMemoryBudgetFactor()
|
||||
{
|
||||
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
|
||||
const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
|
||||
const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() / 2);
|
||||
S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY;
|
||||
if (free_budget < 0)
|
||||
{
|
||||
// Result should range from 1 (0 free budget) to 2 (-512 free budget)
|
||||
return 1.f - free_budget / MIN_FREE_MAIN_MEMORY;
|
||||
// Leave some padding, otherwise we will crash out of memory before hitting factor 2.
|
||||
const S32Megabytes PAD_BUFFER(32);
|
||||
// Result should range from 1 at 0 free budget to 2 at -224 free budget, 2.14 at -256MB
|
||||
return 1.f - free_budget / (MIN_FREE_MAIN_MEMORY - PAD_BUFFER);
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ public:
|
|||
static void initClass();
|
||||
static void updateClass();
|
||||
static bool isSystemMemoryLow();
|
||||
static bool isSystemMemoryCritical();
|
||||
static F32 getSystemMemoryBudgetFactor();
|
||||
|
||||
LLViewerTexture(bool usemipmaps = true);
|
||||
|
|
|
|||
|
|
@ -505,13 +505,11 @@ void LLVOCacheEntry::updateDebugSettings()
|
|||
static const F32 MIN_RADIUS = 1.0f;
|
||||
|
||||
F32 draw_radius = gAgentCamera.mDrawDistance;
|
||||
if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
|
||||
if (LLViewerTexture::isSystemMemoryCritical())
|
||||
{
|
||||
// Discard's bias maximum is 4 so we need to check 2 to 4 range
|
||||
// Factor is intended to go from 1.0 to 2.0
|
||||
F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f;
|
||||
// For safety cap reduction at 50%, we don't want to go below half of draw distance
|
||||
draw_radius = llmax(draw_radius / factor, draw_radius / 2.f);
|
||||
draw_radius = llmax(draw_radius / LLViewerTexture::getSystemMemoryBudgetFactor(), draw_radius / 2.f);
|
||||
}
|
||||
const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
|
||||
sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ void LLVoiceChannel::suspend()
|
|||
{
|
||||
sSuspendedVoiceChannel = sCurrentVoiceChannel;
|
||||
sSuspended = true;
|
||||
|
||||
sCurrentVoiceChannelChangedSignal(sSuspendedVoiceChannel->mSessionID);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,6 +367,7 @@ void LLVoiceChannel::resume()
|
|||
{
|
||||
if (sSuspended)
|
||||
{
|
||||
sSuspended = false; // needs to be before activate() so that observers will be able to read state
|
||||
if (LLVoiceClient::getInstance()->voiceEnabled())
|
||||
{
|
||||
if (sSuspendedVoiceChannel)
|
||||
|
|
@ -382,7 +385,6 @@ void LLVoiceChannel::resume()
|
|||
LLVoiceChannelProximal::getInstance()->activate();
|
||||
}
|
||||
}
|
||||
sSuspended = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ public:
|
|||
|
||||
static void suspend();
|
||||
static void resume();
|
||||
static bool isSuspended() { return sSuspended; }
|
||||
|
||||
protected:
|
||||
virtual void setState(EState state);
|
||||
|
|
|
|||
|
|
@ -82,9 +82,15 @@ const std::string WEBRTC_VOICE_SERVER_TYPE = "webrtc";
|
|||
|
||||
namespace {
|
||||
|
||||
const F32 MAX_AUDIO_DIST = 50.0f;
|
||||
const F32 VOLUME_SCALE_WEBRTC = 0.01f;
|
||||
const F32 LEVEL_SCALE_WEBRTC = 0.008f;
|
||||
const F32 MAX_AUDIO_DIST = 50.0f;
|
||||
const F32 VOLUME_SCALE_WEBRTC = 0.01f;
|
||||
const F32 TUNING_LEVEL_SCALE = 0.01f;
|
||||
const F32 TUNING_LEVEL_START_POINT = 0.8f;
|
||||
const F32 LEVEL_SCALE = 0.005f;
|
||||
const F32 LEVEL_START_POINT = 0.18f;
|
||||
const uint32_t SET_HIDDEN_RESTORE_DELAY_MS = 200; // 200 ms to unmute again after hiding during teleport
|
||||
const uint32_t MUTE_FADE_DELAY_MS = 500; // 20ms fade followed by 480ms silence gets rid of the click just after unmuting.
|
||||
// This is because the buffers and processing is cleared by the silence.
|
||||
|
||||
const F32 SPEAKING_AUDIO_LEVEL = 0.30f; // <FS:minerjr> add missing f for float
|
||||
|
||||
|
|
@ -201,7 +207,6 @@ bool LLWebRTCVoiceClient::sShuttingDown = false;
|
|||
|
||||
LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
|
||||
mHidden(false),
|
||||
mTuningMode(false),
|
||||
mTuningMicGain(0.0),
|
||||
mTuningSpeakerVolume(50), // Set to 50 so the user can hear themselves when he sets his mic volume
|
||||
mDevicesListUpdated(false),
|
||||
|
|
@ -348,25 +353,45 @@ void LLWebRTCVoiceClient::updateSettings()
|
|||
static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
|
||||
setRenderDevice(sOutputDevice);
|
||||
|
||||
LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
|
||||
LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice())
|
||||
<< LL_ENDL;
|
||||
|
||||
static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
|
||||
setMicGain(sMicLevel);
|
||||
|
||||
llwebrtc::LLWebRTCDeviceInterface::AudioConfig config;
|
||||
|
||||
bool audioConfigChanged = false;
|
||||
|
||||
static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true);
|
||||
config.mEchoCancellation = sEchoCancellation;
|
||||
if (sEchoCancellation != config.mEchoCancellation)
|
||||
{
|
||||
config.mEchoCancellation = sEchoCancellation;
|
||||
audioConfigChanged = true;
|
||||
}
|
||||
|
||||
static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true);
|
||||
config.mAGC = sAGC;
|
||||
if (sAGC != config.mAGC)
|
||||
{
|
||||
config.mAGC = sAGC;
|
||||
audioConfigChanged = true;
|
||||
}
|
||||
|
||||
static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings,
|
||||
static LLCachedControl<U32> sNoiseSuppressionLevel(
|
||||
gSavedSettings,
|
||||
"VoiceNoiseSuppressionLevel",
|
||||
llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH);
|
||||
config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel;
|
||||
|
||||
mWebRTCDeviceInterface->setAudioConfig(config);
|
||||
auto noiseSuppressionLevel =
|
||||
(llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel;
|
||||
if (noiseSuppressionLevel != config.mNoiseSuppressionLevel)
|
||||
{
|
||||
config.mNoiseSuppressionLevel = noiseSuppressionLevel;
|
||||
audioConfigChanged = true;
|
||||
}
|
||||
if (audioConfigChanged)
|
||||
{
|
||||
mWebRTCDeviceInterface->setAudioConfig(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -703,21 +728,38 @@ void LLWebRTCVoiceClient::OnDevicesChangedImpl(const llwebrtc::LLWebRTCVoiceDevi
|
|||
std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice");
|
||||
|
||||
LL_DEBUGS("Voice") << "Setting devices to-input: '" << inputDevice << "' output: '" << outputDevice << "'" << LL_ENDL;
|
||||
clearRenderDevices();
|
||||
for (auto &device : render_devices)
|
||||
{
|
||||
addRenderDevice(LLVoiceDevice(device.mDisplayName, device.mID));
|
||||
}
|
||||
setRenderDevice(outputDevice);
|
||||
|
||||
clearCaptureDevices();
|
||||
for (auto &device : capture_devices)
|
||||
// only set the render device if the device list has changed.
|
||||
if (mRenderDevices.size() != render_devices.size() || !std::equal(mRenderDevices.begin(),
|
||||
mRenderDevices.end(),
|
||||
render_devices.begin(),
|
||||
[](const LLVoiceDevice& a, const llwebrtc::LLWebRTCVoiceDevice& b) {
|
||||
return a.display_name == b.mDisplayName && a.full_name == b.mID; }))
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Checking capture device:'" << device.mID << "'" << LL_ENDL;
|
||||
|
||||
addCaptureDevice(LLVoiceDevice(device.mDisplayName, device.mID));
|
||||
clearRenderDevices();
|
||||
for (auto& device : render_devices)
|
||||
{
|
||||
addRenderDevice(LLVoiceDevice(device.mDisplayName, device.mID));
|
||||
}
|
||||
setRenderDevice(outputDevice);
|
||||
}
|
||||
|
||||
// only set the capture device if the device list has changed.
|
||||
if (mCaptureDevices.size() != capture_devices.size() ||!std::equal(mCaptureDevices.begin(),
|
||||
mCaptureDevices.end(),
|
||||
capture_devices.begin(),
|
||||
[](const LLVoiceDevice& a, const llwebrtc::LLWebRTCVoiceDevice& b)
|
||||
{ return a.display_name == b.mDisplayName && a.full_name == b.mID; }))
|
||||
{
|
||||
clearCaptureDevices();
|
||||
for (auto& device : capture_devices)
|
||||
{
|
||||
LL_DEBUGS("Voice") << "Checking capture device:'" << device.mID << "'" << LL_ENDL;
|
||||
|
||||
addCaptureDevice(LLVoiceDevice(device.mDisplayName, device.mID));
|
||||
}
|
||||
setCaptureDevice(inputDevice);
|
||||
}
|
||||
setCaptureDevice(inputDevice);
|
||||
|
||||
setDevicesListUpdated(true);
|
||||
}
|
||||
|
|
@ -770,7 +812,14 @@ bool LLWebRTCVoiceClient::inTuningMode()
|
|||
|
||||
void LLWebRTCVoiceClient::tuningSetMicVolume(float volume)
|
||||
{
|
||||
mTuningMicGain = volume;
|
||||
if (volume != mTuningMicGain)
|
||||
{
|
||||
mTuningMicGain = volume;
|
||||
if (mWebRTCDeviceInterface)
|
||||
{
|
||||
mWebRTCDeviceInterface->setTuningMicGain(volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
|
||||
|
|
@ -782,21 +831,10 @@ void LLWebRTCVoiceClient::tuningSetSpeakerVolume(float volume)
|
|||
}
|
||||
}
|
||||
|
||||
float LLWebRTCVoiceClient::getAudioLevel()
|
||||
{
|
||||
if (mIsInTuningMode)
|
||||
{
|
||||
return (1.0f - mWebRTCDeviceInterface->getTuningAudioLevel() * LEVEL_SCALE_WEBRTC) * mTuningMicGain / 2.1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (1.0f - mWebRTCDeviceInterface->getPeerConnectionAudioLevel() * LEVEL_SCALE_WEBRTC) * mMicGain / 2.1f;
|
||||
}
|
||||
}
|
||||
|
||||
float LLWebRTCVoiceClient::tuningGetEnergy(void)
|
||||
{
|
||||
return getAudioLevel();
|
||||
float rms = mWebRTCDeviceInterface->getTuningAudioLevel();
|
||||
return TUNING_LEVEL_START_POINT - TUNING_LEVEL_SCALE * rms;
|
||||
}
|
||||
|
||||
bool LLWebRTCVoiceClient::deviceSettingsAvailable()
|
||||
|
|
@ -832,6 +870,11 @@ void LLWebRTCVoiceClient::setHidden(bool hidden)
|
|||
|
||||
if (inSpatialChannel())
|
||||
{
|
||||
if (mWebRTCDeviceInterface)
|
||||
{
|
||||
mWebRTCDeviceInterface->setMute(mHidden || mMuteMic,
|
||||
mHidden ? 0 : SET_HIDDEN_RESTORE_DELAY_MS); // delay 200ms so as to not pile up mutes/unmutes.
|
||||
}
|
||||
if (mHidden)
|
||||
{
|
||||
// get out of the channel entirely
|
||||
|
|
@ -998,7 +1041,6 @@ void LLWebRTCVoiceClient::updatePosition(void)
|
|||
{
|
||||
if (participant->mRegion != region->getRegionID()) {
|
||||
participant->mRegion = region->getRegionID();
|
||||
setMuteMic(mMuteMic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1123,13 +1165,14 @@ void LLWebRTCVoiceClient::sendPositionUpdate(bool force)
|
|||
// Update our own volume on our participant, so it'll show up
|
||||
// in the UI. This is done on all sessions, so switching
|
||||
// sessions retains consistent volume levels.
|
||||
void LLWebRTCVoiceClient::updateOwnVolume() {
|
||||
F32 audio_level = 0.0;
|
||||
if (!mMuteMic && !mTuningMode)
|
||||
void LLWebRTCVoiceClient::updateOwnVolume()
|
||||
{
|
||||
F32 audio_level = 0.0f;
|
||||
if (!mMuteMic)
|
||||
{
|
||||
audio_level = getAudioLevel();
|
||||
float rms = mWebRTCDeviceInterface->getPeerConnectionAudioLevel();
|
||||
audio_level = LEVEL_START_POINT - LEVEL_SCALE * rms;
|
||||
}
|
||||
|
||||
sessionState::for_each(boost::bind(predUpdateOwnVolume, _1, audio_level));
|
||||
}
|
||||
|
||||
|
|
@ -1526,6 +1569,17 @@ void LLWebRTCVoiceClient::setMuteMic(bool muted)
|
|||
}
|
||||
|
||||
mMuteMic = muted;
|
||||
|
||||
if (mIsInTuningMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (mWebRTCDeviceInterface)
|
||||
{
|
||||
mWebRTCDeviceInterface->setMute(muted, muted ? MUTE_FADE_DELAY_MS : 0); // delay for 40ms on mute to allow buffers to empty
|
||||
}
|
||||
|
||||
// when you're hidden, your mic is always muted.
|
||||
if (!mHidden)
|
||||
{
|
||||
|
|
@ -1564,7 +1618,10 @@ void LLWebRTCVoiceClient::setMicGain(F32 gain)
|
|||
if (gain != mMicGain)
|
||||
{
|
||||
mMicGain = gain;
|
||||
mWebRTCDeviceInterface->setPeerConnectionGain(gain);
|
||||
if (mWebRTCDeviceInterface)
|
||||
{
|
||||
mWebRTCDeviceInterface->setMicGain(gain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -444,10 +444,6 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
// helper function to retrieve the audio level
|
||||
// Used in multiple places.
|
||||
float getAudioLevel();
|
||||
|
||||
// Coroutine support methods
|
||||
//---
|
||||
void voiceConnectionCoro();
|
||||
|
|
@ -458,7 +454,6 @@ private:
|
|||
|
||||
LL::WorkQueue::weak_t mMainQueue;
|
||||
|
||||
bool mTuningMode;
|
||||
F32 mTuningMicGain;
|
||||
int mTuningSpeakerVolume;
|
||||
bool mDevicesListUpdated; // set to true when the device list has been updated
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@
|
|||
<menu_item_call label="Yeni gün dövrü" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="İşlət:" name="upload_def">
|
||||
<menu_item_call label="Şəkil yükləmək üçün" name="Image uploads"/>
|
||||
<menu_item_call label="Səs yükləmək üçün" name="Sound uploads"/>
|
||||
<menu_item_call label="Animasiya yükləmək üçün" name="Animation uploads"/>
|
||||
<menu_item_call label="Model yükləmək üçün" name="Model uploads"/>
|
||||
<menu_item_check label="Şəkil yükləmək üçün" name="Image uploads"/>
|
||||
<menu_item_check label="Səs yükləmək üçün" name="Sound uploads"/>
|
||||
<menu_item_check label="Animasiya yükləmək üçün" name="Animation uploads"/>
|
||||
<menu_item_check label="Model yükləmək üçün" name="Model uploads"/>
|
||||
</menu>
|
||||
<menu label="Növü dəyişdir" name="Change Type">
|
||||
<menu_item_call label="Susmaya görə" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -93,11 +93,11 @@
|
|||
<menu_item_call label="Mehrfach-Upload..." name="Bulk Upload"/>
|
||||
</menu>
|
||||
<menu label="Als Standard verwenden für" name="upload_def">
|
||||
<menu_item_call label="Hochgeladene Bilder" name="Image uploads"/>
|
||||
<menu_item_call label="Hochgeladene Sounds" name="Sound uploads"/>
|
||||
<menu_item_call label="Hochgeladene Animationen" name="Animation uploads"/>
|
||||
<menu_item_call label="Hochgeladene Modelle" name="Model uploads"/>
|
||||
<menu_item_call label="Hochgeladene PBR-Materialien" name="PBR uploads"/>
|
||||
<menu_item_check label="Hochgeladene Bilder" name="Image uploads"/>
|
||||
<menu_item_check label="Hochgeladene Sounds" name="Sound uploads"/>
|
||||
<menu_item_check label="Hochgeladene Animationen" name="Animation uploads"/>
|
||||
<menu_item_check label="Hochgeladene Modelle" name="Model uploads"/>
|
||||
<menu_item_check label="Hochgeladene PBR-Materialien" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="In Marktplatz-Auflistungen kopieren" name="Marketplace Copy"/>
|
||||
<menu_item_call label="In Marktplatz-Auflistungen verschieben" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@
|
|||
<menu_item_call label="Neuer Tageszyklus" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Als Standard verwenden für" name="upload_def">
|
||||
<menu_item_call label="Hochgeladene Bilder" name="Image uploads"/>
|
||||
<menu_item_call label="Hochgeladene Sounds" name="Sound uploads"/>
|
||||
<menu_item_call label="Hochgeladene Animationen" name="Animation uploads"/>
|
||||
<menu_item_call label="Hochgeladene Modelle" name="Model uploads"/>
|
||||
<menu_item_call label="Hochgeladene PBR-Materialien" name="PBR uploads"/>
|
||||
<menu_item_check label="Hochgeladene Bilder" name="Image uploads"/>
|
||||
<menu_item_check label="Hochgeladene Sounds" name="Sound uploads"/>
|
||||
<menu_item_check label="Hochgeladene Animationen" name="Animation uploads"/>
|
||||
<menu_item_check label="Hochgeladene Modelle" name="Model uploads"/>
|
||||
<menu_item_check label="Hochgeladene PBR-Materialien" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="Als Favoriten-Ordner verwenden" name="Set Favorites folder"/>
|
||||
<menu_item_call label="Favoriten-Ordner zurücksetzen" name="Reset Favorites folder"/>
|
||||
|
|
|
|||
|
|
@ -767,54 +767,69 @@
|
|||
label="Use as default for"
|
||||
layout="topleft"
|
||||
name="upload_def">
|
||||
<menu_item_call
|
||||
<menu_item_check
|
||||
label="Image uploads"
|
||||
layout="topleft"
|
||||
name="Image uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_texture" />
|
||||
<menu_item_call.on_visible
|
||||
<on_visible
|
||||
function="Inventory.CanSetUploadLocation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_texture" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Sound uploads"
|
||||
layout="topleft"
|
||||
name="Sound uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_sound" />
|
||||
<menu_item_call.on_visible
|
||||
<on_visible
|
||||
function="Inventory.CanSetUploadLocation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_sound" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Animation uploads"
|
||||
layout="topleft"
|
||||
name="Animation uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_animation" />
|
||||
<menu_item_call.on_visible
|
||||
<on_visible
|
||||
function="Inventory.CanSetUploadLocation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_animation" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Model uploads"
|
||||
layout="topleft"
|
||||
name="Model uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_model" />
|
||||
<menu_item_call.on_visible
|
||||
<on_visible
|
||||
function="Inventory.CanSetUploadLocation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_model" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="PBR material uploads"
|
||||
layout="topleft"
|
||||
name="PBR uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_pbr_material" />
|
||||
</menu_item_call>
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_pbr_material" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
<menu_item_separator
|
||||
layout="topleft"
|
||||
|
|
|
|||
|
|
@ -394,46 +394,61 @@
|
|||
label="Use as default for"
|
||||
layout="topleft"
|
||||
name="upload_def">
|
||||
<menu_item_call
|
||||
<menu_item_check
|
||||
label="Image uploads"
|
||||
layout="topleft"
|
||||
name="Image uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_texture" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_texture" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Sound uploads"
|
||||
layout="topleft"
|
||||
name="Sound uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_sound" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_sound" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Animation uploads"
|
||||
layout="topleft"
|
||||
name="Animation uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_animation" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_animation" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="Model uploads"
|
||||
layout="topleft"
|
||||
name="Model uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_model" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_model" />
|
||||
</menu_item_check>
|
||||
<menu_item_check
|
||||
label="PBR material uploads"
|
||||
layout="topleft"
|
||||
name="PBR uploads">
|
||||
<menu_item_call.on_click
|
||||
<on_click
|
||||
function="Inventory.FileUploadLocation"
|
||||
parameter="def_pbr_material" />
|
||||
</menu_item_call>
|
||||
<on_check
|
||||
function="Inventory.FileUploadLocation.Check"
|
||||
parameter="def_pbr_material" />
|
||||
</menu_item_check>
|
||||
</menu>
|
||||
<menu
|
||||
label="Change Type"
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@
|
|||
<menu_item_call label="Nuevo Ciclo del día" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Usar como valor predeterminado para" name="upload_def">
|
||||
<menu_item_call label="Imágenes subidas" name="Image uploads"/>
|
||||
<menu_item_call label="Sonidos subidos" name="Sound uploads"/>
|
||||
<menu_item_call label="Animaciones subidas" name="Animation uploads"/>
|
||||
<menu_item_call label="Modelos subidos" name="Model uploads"/>
|
||||
<menu_item_check label="Imágenes subidas" name="Image uploads"/>
|
||||
<menu_item_check label="Sonidos subidos" name="Sound uploads"/>
|
||||
<menu_item_check label="Animaciones subidas" name="Animation uploads"/>
|
||||
<menu_item_check label="Modelos subidos" name="Model uploads"/>
|
||||
</menu>
|
||||
<menu label="Change Type" name="Change Type">
|
||||
<menu_item_call label="Por defecto" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -52,10 +52,11 @@
|
|||
<menu_item_call label="Nouveau dossier à partir de la sélection" name="New folder from selected"/>
|
||||
<menu_item_call label="Annuler le regroupement par dossier" name="Ungroup folder items"/>
|
||||
<menu label="Utiliser par défaut pour" name="upload_def">
|
||||
<menu_item_call label="Le chargement d'images" name="Image uploads"/>
|
||||
<menu_item_call label="Le chargement de sons" name="Sound uploads"/>
|
||||
<menu_item_call label="Le chargement d'animations" name="Animation uploads"/>
|
||||
<menu_item_call label="Le chargement de modèles" name="Model uploads"/>
|
||||
<menu_item_check label="Le chargement d'images" name="Image uploads"/>
|
||||
<menu_item_check label="Le chargement de sons" name="Sound uploads"/>
|
||||
<menu_item_check label="Le chargement d'animations" name="Animation uploads"/>
|
||||
<menu_item_check label="Le chargement de modèles" name="Model uploads"/>
|
||||
<menu_item_check label="Chargements de matériaux PBR" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="Copier dans la liste de Marketplace" name="Marketplace Copy"/>
|
||||
<menu_item_call label="Déplacer vers la liste de Marketplace" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@
|
|||
<menu_item_call label="Nouveau cycle du jour" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Utiliser comme dossier par défaut pour" name="upload_def">
|
||||
<menu_item_call label="Chargements d’images" name="Image uploads"/>
|
||||
<menu_item_call label="Chargements de sons" name="Sound uploads"/>
|
||||
<menu_item_call label="Chargements d’animations" name="Animation uploads"/>
|
||||
<menu_item_call label="Chargements de modèles" name="Model uploads"/>
|
||||
<menu_item_call label="Chargements de matériaux PBR" name="PBR uploads"/>
|
||||
<menu_item_check label="Chargements d’images" name="Image uploads"/>
|
||||
<menu_item_check label="Chargements de sons" name="Sound uploads"/>
|
||||
<menu_item_check label="Chargements d’animations" name="Animation uploads"/>
|
||||
<menu_item_check label="Chargements de modèles" name="Model uploads"/>
|
||||
<menu_item_check label="Chargements de matériaux PBR" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu label="Changer de type" name="Change Type">
|
||||
<menu_item_call label="Défaut" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -85,10 +85,11 @@
|
|||
<menu_item_call label="Crea cartella dagli elementi selezionati" name="New folder from selected" />
|
||||
<menu_item_call label="Separa gli elementi della cartella" name="Ungroup folder items" />
|
||||
<menu label="Usa come predefinita per" name="upload_def">
|
||||
<menu_item_call label="Immagini caricate" name="Image uploads"/>
|
||||
<menu_item_call label="Suoni caricati" name="Sound uploads"/>
|
||||
<menu_item_call label="Animazioni caricate" name="Animation uploads"/>
|
||||
<menu_item_call label="Modelli mesh caricati" name="Model uploads"/>
|
||||
<menu_item_check label="Immagini caricate" name="Image uploads"/>
|
||||
<menu_item_check label="Suoni caricati" name="Sound uploads"/>
|
||||
<menu_item_check label="Animazioni caricate" name="Animation uploads"/>
|
||||
<menu_item_check label="Modelli mesh caricati" name="Model uploads"/>
|
||||
<menu_item_check label="Materiali PBR caricati" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="Copia negli annunci Marketplace" name="Marketplace Copy"/>
|
||||
<menu_item_call label="Sposta negli annunci Marketplace" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@
|
|||
<menu_item_call label="Nuovo ciclo giornata" name="New Day Cycle" />
|
||||
</menu>
|
||||
<menu label="Usa come predefinita per" name="upload_def">
|
||||
<menu_item_call label="Immagini caricate" name="Image uploads"/>
|
||||
<menu_item_call label="Suoni caricati" name="Sound uploads"/>
|
||||
<menu_item_call label="Animazioni caricate" name="Animation uploads"/>
|
||||
<menu_item_call label="Modelli mesh caricati" name="Model uploads"/>
|
||||
<menu_item_call label="Materiali PBR caricati" name="PBR uploads"/>
|
||||
<menu_item_check label="Immagini caricate" name="Image uploads"/>
|
||||
<menu_item_check label="Suoni caricati" name="Sound uploads"/>
|
||||
<menu_item_check label="Animazioni caricate" name="Animation uploads"/>
|
||||
<menu_item_check label="Modelli mesh caricati" name="Model uploads"/>
|
||||
<menu_item_check label="Materiali PBR caricati" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu label="Cambia tipo" name="Change Type">
|
||||
<menu_item_call label="Predefinito" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@
|
|||
<menu_item_call label="一括…" name="Bulk Upload"/>
|
||||
</menu>
|
||||
<menu label="デフォルトのアップロード先" name="upload_def">
|
||||
<menu_item_call label="アップロードした画像" name="Image uploads"/>
|
||||
<menu_item_call label="アップロードしたサウンド" name="Sound uploads"/>
|
||||
<menu_item_call label="アップロードしたアニメーション" name="Animation uploads"/>
|
||||
<menu_item_call label="アップロードしたモデル" name="Model uploads"/>
|
||||
<menu_item_call label="アップロードしたPBRマテリアル" name="PBR uploads"/>
|
||||
<menu_item_check label="アップロードした画像" name="Image uploads"/>
|
||||
<menu_item_check label="アップロードしたサウンド" name="Sound uploads"/>
|
||||
<menu_item_check label="アップロードしたアニメーション" name="Animation uploads"/>
|
||||
<menu_item_check label="アップロードしたモデル" name="Model uploads"/>
|
||||
<menu_item_check label="アップロードしたPBRマテリアル" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="マーケットプレイスの出品リストにコピー" name="Marketplace Copy"/>
|
||||
<menu_item_call label="マーケットプレイスの出品リストに移動" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -133,11 +133,11 @@
|
|||
<menu_item_call label="お気に入りに追加" name="Add to Favorites"/>
|
||||
<menu_item_call label="お気に入りから削除" name="Remove from Favorites"/>
|
||||
<menu label="以下のデフォルトとして使用" name="upload_def">
|
||||
<menu_item_call label="画像のアップロード" name="Image uploads"/>
|
||||
<menu_item_call label="サウンドのアップロード" name="Sound uploads"/>
|
||||
<menu_item_call label="アニメーションのアップロード" name="Animation uploads"/>
|
||||
<menu_item_call label="モデルのアップロード" name="Model uploads"/>
|
||||
<menu_item_call label="PBRマテリアルのアップロード" name="PBR uploads"/>
|
||||
<menu_item_check label="画像のアップロード" name="Image uploads"/>
|
||||
<menu_item_check label="サウンドのアップロード" name="Sound uploads"/>
|
||||
<menu_item_check label="アニメーションのアップロード" name="Animation uploads"/>
|
||||
<menu_item_check label="モデルのアップロード" name="Model uploads"/>
|
||||
<menu_item_check label="PBRマテリアルのアップロード" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="マーケットプレイスの出品リストにコピー" name="Marketplace Copy"/>
|
||||
<menu_item_call label="マーケットプレイスの出品リストに移動" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@
|
|||
<menu_item_call label="Zbiór wielu plików..." name="Bulk Upload" />
|
||||
</menu>
|
||||
<menu label="Ustaw jako domyślne" name="upload_def">
|
||||
<menu_item_call label="Dla nowych obrazów" name="Image uploads" />
|
||||
<menu_item_call label="Dla nowych dźwięków" name="Sound uploads" />
|
||||
<menu_item_call label="Dla nowych animacji" name="Animation uploads" />
|
||||
<menu_item_call label="Dla nowych modeli" name="Model uploads" />
|
||||
<menu_item_call label="Dla nowych materiałów PBR" name="PBR uploads" />
|
||||
<menu_item_check label="Dla nowych obrazów" name="Image uploads" />
|
||||
<menu_item_check label="Dla nowych dźwięków" name="Sound uploads" />
|
||||
<menu_item_check label="Dla nowych animacji" name="Animation uploads" />
|
||||
<menu_item_check label="Dla nowych modeli" name="Model uploads" />
|
||||
<menu_item_check label="Dla nowych materiałów PBR" name="PBR uploads" />
|
||||
</menu>
|
||||
<menu_item_call label="Kopiuj do rzeczy Marketplace" name="Marketplace Copy" />
|
||||
<menu_item_call label="Przenieś do rzeczy Marketplace" name="Marketplace Move" />
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@
|
|||
<menu_item_call label="Nowy cykl dnia" name="New Day Cycle" />
|
||||
</menu>
|
||||
<menu label="Ustaw jako domyślne" name="upload_def">
|
||||
<menu_item_call label="Dla nowych obrazów" name="Image uploads" />
|
||||
<menu_item_call label="Dla nowych dźwięków" name="Sound uploads" />
|
||||
<menu_item_call label="Dla nowych animacji" name="Animation uploads" />
|
||||
<menu_item_call label="Dla nowych modeli" name="Model uploads" />
|
||||
<menu_item_call label="Dla nowych materiałów PBR" name="PBR uploads" />
|
||||
<menu_item_check label="Dla nowych obrazów" name="Image uploads" />
|
||||
<menu_item_check label="Dla nowych dźwięków" name="Sound uploads" />
|
||||
<menu_item_check label="Dla nowych animacji" name="Animation uploads" />
|
||||
<menu_item_check label="Dla nowych modeli" name="Model uploads" />
|
||||
<menu_item_check label="Dla nowych materiałów PBR" name="PBR uploads" />
|
||||
</menu>
|
||||
<menu label="Zmień typ" name="Change Type">
|
||||
<menu_item_call label="Domyślny" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@
|
|||
<menu_item_call label="Novo ciclo de dias" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Usar como padrão para" name="upload_def">
|
||||
<menu_item_call label="Envios de imagem" name="Image uploads"/>
|
||||
<menu_item_call label="Envios de som" name="Sound uploads"/>
|
||||
<menu_item_call label="Envios de animação" name="Animation uploads"/>
|
||||
<menu_item_call label="Envios de modelos" name="Model uploads"/>
|
||||
<menu_item_check label="Envios de imagem" name="Image uploads"/>
|
||||
<menu_item_check label="Envios de som" name="Sound uploads"/>
|
||||
<menu_item_check label="Envios de animação" name="Animation uploads"/>
|
||||
<menu_item_check label="Envios de modelos" name="Model uploads"/>
|
||||
</menu>
|
||||
<menu label="Alterar fonte" name="Change Type">
|
||||
<menu_item_call label="Padrão" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@
|
|||
<menu_item_call label="Масса..." name="Bulk Upload"/>
|
||||
</menu>
|
||||
<menu label="Использовать по умолчанию для" name="upload_def">
|
||||
<menu_item_call label="Загрузки изображений" name="Image uploads"/>
|
||||
<menu_item_call label="Загрузки звука" name="Sound uploads"/>
|
||||
<menu_item_call label="Загрузки анимации" name="Animation uploads"/>
|
||||
<menu_item_call label="Загрузки модели" name="Model uploads"/>
|
||||
<menu_item_call label="Загрузки PBR материала" name="PBR uploads"/>
|
||||
<menu_item_check label="Загрузки изображений" name="Image uploads"/>
|
||||
<menu_item_check label="Загрузки звука" name="Sound uploads"/>
|
||||
<menu_item_check label="Загрузки анимации" name="Animation uploads"/>
|
||||
<menu_item_check label="Загрузки модели" name="Model uploads"/>
|
||||
<menu_item_check label="Загрузки PBR материала" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu_item_call label="Копировать в списки торговой площадки" name="Marketplace Copy"/>
|
||||
<menu_item_call label="Перейти в списки торговой площадки" name="Marketplace Move"/>
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@
|
|||
<menu_item_call label="Новый Цикл дня" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Использовать для" name="upload_def">
|
||||
<menu_item_call label="загрузок Изображений" name="Image uploads"/>
|
||||
<menu_item_call label="загрузок Звуков" name="Sound uploads"/>
|
||||
<menu_item_call label="загрузок Анимаций" name="Animation uploads"/>
|
||||
<menu_item_call label="загрузок Моделей" name="Model uploads"/>
|
||||
<menu_item_call label="загрузок Материалов PBR" name="PBR uploads"/>
|
||||
<menu_item_check label="загрузок Изображений" name="Image uploads"/>
|
||||
<menu_item_check label="загрузок Звуков" name="Sound uploads"/>
|
||||
<menu_item_check label="загрузок Анимаций" name="Animation uploads"/>
|
||||
<menu_item_check label="загрузок Моделей" name="Model uploads"/>
|
||||
<menu_item_check label="загрузок Материалов PBR" name="PBR uploads"/>
|
||||
</menu>
|
||||
<menu label="Изменить тип" name="Change Type">
|
||||
<menu_item_call label="По умолчанию" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -48,10 +48,10 @@
|
|||
<menu_item_call label="Yeni Gün Döngüsü" name="New Day Cycle"/>
|
||||
</menu>
|
||||
<menu label="Şunun için varsayılan olarak kullan" name="upload_def">
|
||||
<menu_item_call label="Karşıya yüklenen görüntüler" name="Image uploads"/>
|
||||
<menu_item_call label="Karşıya yüklenen sesler" name="Sound uploads"/>
|
||||
<menu_item_call label="Karşıya yüklenen animasyonlar" name="Animation uploads"/>
|
||||
<menu_item_call label="Karşıya yüklenen modeller" name="Model uploads"/>
|
||||
<menu_item_check label="Karşıya yüklenen görüntüler" name="Image uploads"/>
|
||||
<menu_item_check label="Karşıya yüklenen sesler" name="Sound uploads"/>
|
||||
<menu_item_check label="Karşıya yüklenen animasyonlar" name="Animation uploads"/>
|
||||
<menu_item_check label="Karşıya yüklenen modeller" name="Model uploads"/>
|
||||
</menu>
|
||||
<menu label="Türü Değiştir" name="Change Type">
|
||||
<menu_item_call label="Varsayılan" name="Default"/>
|
||||
|
|
|
|||
|
|
@ -95,11 +95,11 @@
|
|||
<menu_item_call label="批量上傳..." name="Bulk Upload" />
|
||||
</menu>
|
||||
<menu label="預設用作" name="upload_def">
|
||||
<menu_item_call label="上傳圖像" name="Image uploads" />
|
||||
<menu_item_call label="上傳聲音" name="Sound uploads" />
|
||||
<menu_item_call label="上傳動畫" name="Animation uploads" />
|
||||
<menu_item_call label="上傳模型" name="Model uploads" />
|
||||
<menu_item_call label="上傳PBR材質" name="PBR uploads" />
|
||||
<menu_item_check label="上傳圖像" name="Image uploads" />
|
||||
<menu_item_check label="上傳聲音" name="Sound uploads" />
|
||||
<menu_item_check label="上傳動畫" name="Animation uploads" />
|
||||
<menu_item_check label="上傳模型" name="Model uploads" />
|
||||
<menu_item_check label="上傳PBR材質" name="PBR uploads" />
|
||||
</menu>
|
||||
<menu_item_call label="複製到市場刊登" name="Marketplace Copy" />
|
||||
<menu_item_call label="移到市場刊登" name="Marketplace Move" />
|
||||
|
|
|
|||
|
|
@ -52,11 +52,11 @@
|
|||
<menu_item_call label="新的晝夜循環" name="New Day Cycle" />
|
||||
</menu>
|
||||
<menu label="預設用作" name="upload_def">
|
||||
<menu_item_call label="圖像上傳" name="Image uploads" />
|
||||
<menu_item_call label="聲音上傳" name="Sound uploads" />
|
||||
<menu_item_call label="動畫上傳" name="Animation uploads" />
|
||||
<menu_item_call label="模型上傳" name="Model uploads" />
|
||||
<menu_item_call label="PBR材質上傳" name="PBR uploads" />
|
||||
<menu_item_check label="圖像上傳" name="Image uploads" />
|
||||
<menu_item_check label="聲音上傳" name="Sound uploads" />
|
||||
<menu_item_check label="動畫上傳" name="Animation uploads" />
|
||||
<menu_item_check label="模型上傳" name="Model uploads" />
|
||||
<menu_item_check label="PBR材質上傳" name="PBR uploads" />
|
||||
</menu>
|
||||
<menu_item_call label="作為收藏夾使用" name="Set Favorites folder" />
|
||||
<menu_item_call label="重設收藏夾" name="Reset Favorites folder" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue