Overte C++ Documentation
AudioClient.h
1 //
2 // AudioClient.h
3 // libraries/audio-client/src
4 //
5 // Created by Stephen Birarda on 1/22/13.
6 // Copyright 2013 High Fidelity, Inc.
7 // Copyright 2021 Vircadia contributors.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_AudioClient_h
14 #define hifi_AudioClient_h
15 
16 #include <fstream>
17 #include <memory>
18 #include <vector>
19 #include <mutex>
20 #include <queue>
21 
22 #include <QFuture>
23 #include <QtCore/QtGlobal>
24 #include <QtCore/QByteArray>
25 #include <QtCore/QElapsedTimer>
26 #include <QtCore/QObject>
27 #include <QtCore/QSharedPointer>
28 #include <QtCore/QVector>
29 #include <QtMultimedia/QAudio>
30 #include <QtMultimedia/QAudioFormat>
31 #include <QtMultimedia/QAudioInput>
32 #include <AbstractAudioInterface.h>
33 #include <AudioEffectOptions.h>
34 #include <AudioStreamStats.h>
35 #include <shared/WebRTC.h>
36 
37 #include <DependencyManager.h>
38 #include <SockAddr.h>
39 #include <NLPacket.h>
40 #include <MixedProcessedAudioStream.h>
41 #include <RingBufferHistory.h>
42 #include <SettingHandle.h>
43 #include <Sound.h>
44 #include <StDev.h>
45 #include <AudioHRTF.h>
46 #include <AudioSRC.h>
47 #include <AudioInjector.h>
48 #include <AudioReverb.h>
49 #include <AudioLimiter.h>
50 #include <AudioConstants.h>
51 #include <AudioGate.h>
52 
53 #include <shared/RateCounter.h>
54 
55 #include <plugins/CodecPlugin.h>
56 
57 #include "AudioIOStats.h"
58 #include "AudioFileWav.h"
59 #include "HifiAudioDeviceInfo.h"
60 
61 #if defined(WEBRTC_AUDIO)
62 # define WEBRTC_APM_DEBUG_DUMP 0
63 # include <modules/audio_processing/include/audio_processing.h>
64 # include "modules/audio_processing/audio_processing_impl.h"
65 #endif
66 
67 #ifdef _WIN32
68 #pragma warning( push )
69 #pragma warning( disable : 4273 )
70 #pragma warning( disable : 4305 )
71 #endif
72 
73 #ifdef _WIN32
74 #pragma warning( pop )
75 #endif
76 
77 #if defined (Q_OS_ANDROID)
78 #define VOICE_RECOGNITION "voicerecognition"
79 #define VOICE_COMMUNICATION "voicecommunication"
80 
81 #define SETTING_AEC_KEY "Android/aec"
82 #define DEFAULT_AEC_ENABLED true
83 #endif
84 
85 class QAudioInput;
86 class QAudioOutput;
87 class QIODevice;
88 
89 class Transform;
90 class NLPacket;
91 
92 #define DEFAULT_STARVE_DETECTION_ENABLED true
93 #define DEFAULT_BUFFER_FRAMES 1
94 
95 class AudioClient : public AbstractAudioInterface, public Dependency {
96  Q_OBJECT
97  SINGLETON_DEPENDENCY
98 
99  using LocalInjectorsStream = AudioMixRingBuffer;
100 public:
101  static const int MIN_BUFFER_FRAMES;
102  static const int MAX_BUFFER_FRAMES;
103 
104  using AudioPositionGetter = std::function<glm::vec3()>;
105  using AudioOrientationGetter = std::function<glm::quat()>;
106 
107  using Mutex = std::mutex;
108  using Lock = std::unique_lock<Mutex>;
109 
110  class AudioOutputIODevice : public QIODevice {
111  public:
112  AudioOutputIODevice(LocalInjectorsStream& localInjectorsStream, MixedProcessedAudioStream& receivedAudioStream,
113  AudioClient* audio) :
114  _localInjectorsStream(localInjectorsStream), _receivedAudioStream(receivedAudioStream),
115  _audio(audio), _unfulfilledReads(0) {}
116 
117  void start() { open(QIODevice::ReadOnly | QIODevice::Unbuffered); }
118  qint64 readData(char* data, qint64 maxSize) override;
119  qint64 writeData(const char* data, qint64 maxSize) override { return 0; }
120  int getRecentUnfulfilledReads() { int unfulfilledReads = _unfulfilledReads; _unfulfilledReads = 0; return unfulfilledReads; }
121  private:
122  LocalInjectorsStream& _localInjectorsStream;
123  MixedProcessedAudioStream& _receivedAudioStream;
124  AudioClient* _audio;
125  int _unfulfilledReads;
126  };
127 
128  void startThread();
129  void negotiateAudioFormat();
130  void selectAudioFormat(const QString& selectedCodecName);
131 
132  Q_INVOKABLE QString getSelectedAudioFormat() const { return _selectedCodecName; }
133  Q_INVOKABLE bool getNoiseGateOpen() const { return _audioGateOpen; }
134  Q_INVOKABLE float getSilentInboundPPS() const { return _silentInbound.rate(); }
135  Q_INVOKABLE float getAudioInboundPPS() const { return _audioInbound.rate(); }
136  Q_INVOKABLE float getSilentOutboundPPS() const { return _silentOutbound.rate(); }
137  Q_INVOKABLE float getAudioOutboundPPS() const { return _audioOutbound.rate(); }
138 
139  const MixedProcessedAudioStream& getReceivedAudioStream() const { return _receivedAudioStream; }
140  MixedProcessedAudioStream& getReceivedAudioStream() { return _receivedAudioStream; }
141 
142  const QAudioFormat& getOutputFormat() const { return _outputFormat; }
143 
144  float getLastInputLoudness() const { return _lastInputLoudness; }
145 
146  float getTimeSinceLastClip() const { return _timeSinceLastClip; }
147  float getAudioAverageInputLoudness() const { return _lastInputLoudness; }
148 
149  const AudioIOStats& getStats() const { return _stats; }
150 
151  int getOutputBufferSize() { return _outputBufferSizeFrames.get(); }
152 
153  bool getOutputStarveDetectionEnabled() { return _outputStarveDetectionEnabled.get(); }
154  void setOutputStarveDetectionEnabled(bool enabled) { _outputStarveDetectionEnabled.set(enabled); }
155 
156  bool isSimulatingJitter() { return _gate.isSimulatingJitter(); }
157  void setIsSimulatingJitter(bool enable) { _gate.setIsSimulatingJitter(enable); }
158 
159  int getGateThreshold() { return _gate.getThreshold(); }
160  void setGateThreshold(int threshold) { _gate.setThreshold(threshold); }
161 
162  void setPositionGetter(AudioPositionGetter positionGetter) { _positionGetter = positionGetter; }
163  void setOrientationGetter(AudioOrientationGetter orientationGetter) { _orientationGetter = orientationGetter; }
164 
165  void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; }
166 
167  Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
168 
169  bool outputLocalInjector(const AudioInjectorPointer& injector) override;
170 
171  HifiAudioDeviceInfo getActiveAudioDevice(QAudio::Mode mode) const;
172  QList<HifiAudioDeviceInfo> getAudioDevices(QAudio::Mode mode) const;
173 
174  void enablePeakValues(bool enable) { _enablePeakValues = enable; }
175  bool peakValuesAvailable() const;
176 
177  static const float CALLBACK_ACCELERATOR_RATIO;
178 
179  bool getNamedAudioDeviceForModeExists(QAudio::Mode mode, const QString& deviceName);
180 
181  void setRecording(bool isRecording) { _isRecording = isRecording; };
182  bool getRecording() { return _isRecording; };
183 
184  bool startRecording(const QString& filename);
185  void stopRecording();
186  void setAudioPaused(bool pause);
187 
188  AudioSolo& getAudioSolo() override { return _solo; }
189 
190 #ifdef Q_OS_WIN
191  static QString getWinDeviceName(wchar_t* guid);
192 #endif
193 
194 #if defined(Q_OS_ANDROID)
195  bool isHeadsetPluggedIn() { return _isHeadsetPluggedIn; }
196 #endif
197 
198  int getNumLocalInjectors();
199 
200 public slots:
201  void start();
202  void stop();
203 
204  void handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessage> message);
205  void handleAudioDataPacket(QSharedPointer<ReceivedMessage> message);
206  void handleNoisyMutePacket(QSharedPointer<ReceivedMessage> message);
207  void handleMuteEnvironmentPacket(QSharedPointer<ReceivedMessage> message);
208  void handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> message);
209  void handleMismatchAudioFormat(SharedNodePointer node, const QString& currentCodec, const QString& recievedCodec);
210 
211  void sendDownstreamAudioStatsPacket() { _stats.publish(); }
212  void handleMicAudioInput();
213  void audioInputStateChanged(QAudio::State state);
214  void checkInputTimeout();
215  void handleDummyAudioInput();
216  void handleRecordedAudioInput(const QByteArray& audio);
217  void reset();
218  void audioMixerKilled();
219 
220  void setMuted(bool muted, bool emitSignal = true);
221  bool isMuted() { return _isMuted; }
222 
223  virtual bool setIsStereoInput(bool stereo) override;
224  virtual bool isStereoInput() override { return _isStereoInput; }
225 
226  void setNoiseReduction(bool isNoiseGateEnabled, bool emitSignal = true);
227  bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; }
228 
229  void setNoiseReductionAutomatic(bool isNoiseGateAutomatic, bool emitSignal = true);
230  bool isNoiseReductionAutomatic() const { return _isNoiseReductionAutomatic; }
231 
232  void setNoiseReductionThreshold(float noiseReductionThreshold, bool emitSignal = true);
233  float noiseReductionThreshold() const { return _noiseReductionThreshold; }
234 
235  void setWarnWhenMuted(bool isNoiseGateEnabled, bool emitSignal = true);
236  bool isWarnWhenMutedEnabled() const { return _warnWhenMuted; }
237 
238  void setAcousticEchoCancellation(bool isAECEnabled, bool emitSignal = true);
239  bool isAcousticEchoCancellationEnabled() const { return _isAECEnabled; }
240 
241  virtual bool getLocalEcho() override { return _shouldEchoLocally; }
242  virtual void setLocalEcho(bool localEcho) override { _shouldEchoLocally = localEcho; }
243  virtual void toggleLocalEcho() override { _shouldEchoLocally = !_shouldEchoLocally; }
244 
245  virtual bool getServerEcho() override { return _shouldEchoToServer; }
246  virtual void setServerEcho(bool serverEcho) override { _shouldEchoToServer = serverEcho; }
247  virtual void toggleServerEcho() override { _shouldEchoToServer = !_shouldEchoToServer; }
248 
249  void processReceivedSamples(const QByteArray& inputBuffer, QByteArray& outputBuffer);
250  void sendMuteEnvironmentPacket();
251 
252  int setOutputBufferSize(int numFrames, bool persist = true);
253 
254  bool shouldLoopbackInjectors() override { return _shouldEchoToServer; }
255 
256  // calling with a null QAudioDevice will use the system default
257  bool switchAudioDevice(QAudio::Mode mode, const HifiAudioDeviceInfo& deviceInfo = HifiAudioDeviceInfo());
258  bool switchAudioDevice(QAudio::Mode mode, const QString& deviceName, bool isHmd);
259  void setHmdAudioName(QAudio::Mode mode, const QString& name);
260  // Qt opensles plugin is not able to detect when the headset is plugged in
261  void setHeadsetPluggedIn(bool pluggedIn);
262 
263  float getInputVolume() const { return (_audioInput) ? (float)_audioInput->volume() : 0.0f; }
264  void setInputVolume(float volume, bool emitSignal = true);
265  void setReverb(bool reverb);
266  void setReverbOptions(const AudioEffectOptions* options);
267 
268  void setLocalInjectorGain(float gain) { _localInjectorGain = gain; };
269  void setSystemInjectorGain(float gain) { _systemInjectorGain = gain; };
270  void setOutputGain(float gain) { _outputGain = gain; };
271 
272  void outputNotify();
273  void noteAwakening();
274 
275  void loadSettings();
276  void saveSettings();
277 
278 signals:
279  void inputVolumeChanged(float volume);
280  void muteToggled(bool muted);
281  void noiseReductionChanged(bool noiseReductionEnabled);
282  void noiseReductionAutomaticChanged(bool noiseReductionAutomatic);
283  void noiseReductionThresholdChanged(bool noiseReductionThreshold);
284  void warnWhenMutedChanged(bool warnWhenMutedEnabled);
285  void acousticEchoCancellationChanged(bool acousticEchoCancellationEnabled);
286  void mutedByMixer();
287  void inputReceived(const QByteArray& inputSamples);
288  void inputLoudnessChanged(float loudness, bool isClipping);
289  void outputBytesToNetwork(int numBytes);
290  void inputBytesFromNetwork(int numBytes);
291  void noiseGateOpened();
292  void noiseGateClosed();
293 
294  void changeDevice(const HifiAudioDeviceInfo& outputDeviceInfo);
295 
296  void deviceChanged(QAudio::Mode mode, const HifiAudioDeviceInfo& device);
297  void devicesChanged(QAudio::Mode mode, const QList<HifiAudioDeviceInfo>& devices);
298  void peakValueListChanged(const QList<float> peakValueList);
299 
300  void receivedFirstPacket();
301  void disconnected();
302 
303  void audioFinished();
304 
305  void muteEnvironmentRequested(glm::vec3 position, float radius);
306 
307  void outputBufferReceived(const QByteArray _outputBuffer);
308 
309 protected:
310  AudioClient();
311  ~AudioClient();
312 
313  virtual void customDeleter() override;
314 
315 private:
316  static const int RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES{ 100 };
317  // OUTPUT_CHANNEL_COUNT is audio pipeline output format, which is always 2 channel.
318  // _outputFormat.channelCount() is device output format, which may be 1 or multichannel.
319  static const int OUTPUT_CHANNEL_COUNT{ 2 };
320  static const int STARVE_DETECTION_THRESHOLD{ 3 };
321  static const int STARVE_DETECTION_PERIOD{ 10 * 1000 }; // 10 Seconds
322 
323  static const AudioPositionGetter DEFAULT_POSITION_GETTER;
324  static const AudioOrientationGetter DEFAULT_ORIENTATION_GETTER;
325 
326  friend class CheckDevicesThread;
327  friend class LocalInjectorsThread;
328 
329  float loudnessToLevel(float loudness);
330 
331  // background tasks
332  void checkDevices();
333  void checkPeakValues();
334 
335  void outputFormatChanged();
336  void handleAudioInput(QByteArray& audioBuffer);
337  void prepareLocalAudioInjectors(std::unique_ptr<Lock> localAudioLock = nullptr);
338  bool mixLocalAudioInjectors(float* mixBuffer);
339  float azimuthForSource(const glm::vec3& relativePosition);
340  float gainForSource(float distance, float volume);
341 
342 #ifdef Q_OS_ANDROID
343  QTimer _checkInputTimer{ this };
344  long _inputReadsSinceLastCheck = 0l;
345  bool _isHeadsetPluggedIn { false };
346 #endif
347 
348  class Gate {
349  public:
350  Gate(AudioClient* audioClient);
351 
352  bool isSimulatingJitter() { return _isSimulatingJitter; }
353  void setIsSimulatingJitter(bool enable);
354 
355  int getThreshold() { return _threshold; }
356  void setThreshold(int threshold);
357 
358  void insert(QSharedPointer<ReceivedMessage> message);
359 
360  private:
361  void flush();
362 
363  AudioClient* _audioClient;
364  std::queue<QSharedPointer<ReceivedMessage>> _queue;
365  std::mutex _mutex;
366 
367  int _index{ 0 };
368  int _threshold{ 1 };
369  bool _isSimulatingJitter{ false };
370  };
371 
372  Gate _gate{ this };
373 
374  Mutex _injectorsMutex;
375  QAudioInput* _audioInput{ nullptr };
376  QTimer* _dummyAudioInput{ nullptr };
377  QAudioFormat _desiredInputFormat;
378  QAudioFormat _inputFormat;
379  QIODevice* _inputDevice{ nullptr };
380  int _numInputCallbackBytes{ 0 };
381  QAudioOutput* _audioOutput{ nullptr };
382  std::atomic<bool> _audioOutputInitialized { false };
383  QAudioFormat _desiredOutputFormat;
384  QAudioFormat _outputFormat;
385  int _outputFrameSize{ 0 };
386  int _numOutputCallbackBytes{ 0 };
387  QAudioOutput* _loopbackAudioOutput{ nullptr };
388  QIODevice* _loopbackOutputDevice{ nullptr };
389  AudioRingBuffer _inputRingBuffer{ 0 };
390  LocalInjectorsStream _localInjectorsStream{ 0 , 1 };
391  // In order to use _localInjectorsStream as a lock-free pipe,
392  // use it with a single producer/consumer, and track available samples and injectors
393  std::atomic<int> _localSamplesAvailable { 0 };
394  std::atomic<bool> _localInjectorsAvailable { false };
395  MixedProcessedAudioStream _receivedAudioStream{ RECEIVED_AUDIO_STREAM_CAPACITY_FRAMES };
396  bool _isStereoInput{ false };
397  std::atomic<bool> _enablePeakValues { false };
398 
399  quint64 _outputStarveDetectionStartTimeMsec{ 0 };
400  int _outputStarveDetectionCount { 0 };
401 
402  Setting::Handle<int> _outputBufferSizeFrames{"audioOutputBufferFrames", DEFAULT_BUFFER_FRAMES};
403  int _sessionOutputBufferSizeFrames{ _outputBufferSizeFrames.get() };
404  Setting::Handle<bool> _outputStarveDetectionEnabled{ "audioOutputStarveDetectionEnabled", DEFAULT_STARVE_DETECTION_ENABLED};
405 
406  StDev _stdev;
407  QElapsedTimer _timeSinceLastReceived;
408  float _lastRawInputLoudness{ 0.0f }; // before mute/gate
409  float _lastSmoothedRawInputLoudness{ 0.0f };
410  float _lastInputLoudness{ 0.0f }; // after mute/gate
411  float _timeSinceLastClip{ -1.0f };
412  int _totalInputAudioSamples;
413 
414  bool _isMuted{ false };
415  bool _shouldEchoLocally{ false };
416  bool _shouldEchoToServer{ false };
417  bool _isNoiseGateEnabled{ true };
418  bool _isNoiseReductionAutomatic{ true };
419  float _noiseReductionThreshold{ 0.1f };
420  bool _warnWhenMuted;
421  bool _isAECEnabled{ true };
422 
423  bool _reverb{ false };
424  AudioEffectOptions _scriptReverbOptions;
425  AudioEffectOptions _zoneReverbOptions;
426  AudioEffectOptions* _reverbOptions{ &_scriptReverbOptions };
427  AudioReverb _sourceReverb { AudioConstants::SAMPLE_RATE };
428  AudioReverb _listenerReverb { AudioConstants::SAMPLE_RATE };
429  AudioReverb _localReverb { AudioConstants::SAMPLE_RATE };
430 
431  // possible streams needed for resample
432  AudioSRC* _inputToNetworkResampler{ nullptr };
433  AudioSRC* _networkToOutputResampler{ nullptr };
434  AudioSRC* _localToOutputResampler{ nullptr };
435  AudioSRC* _loopbackResampler{ nullptr };
436 
437  // for network audio (used by network audio thread)
438  int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
439 
440  // for output audio (used by this thread)
441  int _outputPeriod { 0 };
442  float* _outputMixBuffer { NULL };
443  int16_t* _outputScratchBuffer { NULL };
444  std::atomic<float> _outputGain { 1.0f };
445  float _lastOutputGain { 1.0f };
446 
447  // for local audio (used by audio injectors thread)
448  std::atomic<float> _localInjectorGain { 1.0f };
449  std::atomic<float> _systemInjectorGain { 1.0f };
450  float _localMixBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_STEREO];
451  int16_t _localScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
452  float* _localOutputMixBuffer { NULL };
453  Mutex _localAudioMutex;
454  AudioLimiter _audioLimiter{ AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT };
455 
456  // Adds Reverb
457  void configureReverb();
458  void updateReverbOptions();
459  void handleLocalEchoAndReverb(QByteArray& inputByteArray);
460 
461 #if defined(WEBRTC_AUDIO)
462  static const int WEBRTC_SAMPLE_RATE_MAX = 96000;
463  static const int WEBRTC_CHANNELS_MAX = 2;
464  static const int WEBRTC_FRAMES_MAX = webrtc::AudioProcessing::kChunkSizeMs * WEBRTC_SAMPLE_RATE_MAX / 1000;
465 
466  webrtc::AudioProcessing* _apm { nullptr };
467 
468  int16_t _fifoFarEnd[WEBRTC_CHANNELS_MAX * WEBRTC_FRAMES_MAX] {};
469  int _numFifoFarEnd = 0; // numFrames saved in fifo
470 
471  void configureWebrtc();
472  void processWebrtcFarEnd(const int16_t* samples, int numFrames, int numChannels, int sampleRate);
473  void processWebrtcNearEnd(int16_t* samples, int numFrames, int numChannels, int sampleRate);
474 #endif
475 
476  bool switchInputToAudioDevice(const HifiAudioDeviceInfo inputDeviceInfo, bool isShutdownRequest = false);
477  bool switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest = false);
478 
479  // Callback acceleration dependent calculations
480  int calculateNumberOfInputCallbackBytes(const QAudioFormat& format) const;
481  int calculateNumberOfFrameSamples(int numBytes) const;
482 
483  quint16 _outgoingAvatarAudioSequenceNumber{ 0 };
484 
485  AudioOutputIODevice _audioOutputIODevice{ _localInjectorsStream, _receivedAudioStream, this };
486 
487  AudioIOStats _stats{ &_receivedAudioStream };
488 
489  AudioGate* _audioGate { nullptr };
490  bool _audioGateOpen { true };
491 
492  AudioPositionGetter _positionGetter{ DEFAULT_POSITION_GETTER };
493  AudioOrientationGetter _orientationGetter{ DEFAULT_ORIENTATION_GETTER };
494 
495  glm::vec3 avatarBoundingBoxCorner;
496  glm::vec3 avatarBoundingBoxScale;
497 
498  HifiAudioDeviceInfo _inputDeviceInfo;
499  HifiAudioDeviceInfo _outputDeviceInfo;
500 
501  QList<HifiAudioDeviceInfo> _inputDevices;
502  QList<HifiAudioDeviceInfo> _outputDevices;
503 
504  QString _hmdInputName { QString() };
505  QString _hmdOutputName{ QString() };
506 
507  AudioFileWav _audioFileWav;
508 
509  bool _hasReceivedFirstPacket { false };
510 
511  QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
512 
513  bool _isPlayingBackRecording { false };
514  bool _audioPaused { false };
515 
516  CodecPluginPointer _codec;
517  QString _selectedCodecName;
518  Encoder* _encoder { nullptr }; // for outbound mic stream
519 
520  RateCounter<> _silentOutbound;
521  RateCounter<> _audioOutbound;
522  RateCounter<> _silentInbound;
523  RateCounter<> _audioInbound;
524 
525 #if defined(Q_OS_ANDROID)
526  bool _shouldRestartInputSetup { true }; // Should we restart the input device because of an unintended stop?
527 #endif
528 
529  AudioSolo _solo;
530 
531  QFuture<void> _localPrepInjectorFuture;
532  QReadWriteLock _hmdNameLock;
533  Mutex _checkDevicesMutex;
534  QTimer* _checkDevicesTimer { nullptr };
535  Mutex _checkPeakValuesMutex;
536  QTimer* _checkPeakValuesTimer { nullptr };
537 
538  bool _isRecording { false };
539 };
540 
541 
542 #endif // hifi_AudioClient_h
T get() const
Returns the value of the setting, or the default value if not found.
Definition: SettingHandle.h:240