Ring Daemon 16.0.0
Loading...
Searching...
No Matches
preferences.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include "preferences.h"
23#include "logger.h"
24#include "audio/audiolayer.h"
25#if HAVE_OPENSL
27#else
28#if HAVE_ALSA
30#endif
31#if HAVE_JACK
33#endif
34#if HAVE_PULSE
36#endif
37#if HAVE_COREAUDIO
38#ifdef __APPLE__
39#include <TargetConditionals.h>
40#endif
41#if TARGET_OS_IOS
43#else
45#endif /* TARGET_OS_IOS */
46#endif /* HAVE_COREAUDIO */
47#if HAVE_PORTAUDIO
49#endif
50#endif /* HAVE_OPENSL */
51
52#ifdef ENABLE_VIDEO
53#include "client/videomanager.h"
54#endif
55
56#pragma GCC diagnostic push
57#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
58#include <yaml-cpp/yaml.h>
59#pragma GCC diagnostic pop
60
61#include "config/yamlparser.h"
63#include <sstream>
64#include <algorithm>
65#include <stdexcept>
66#include "fileutils.h"
67#include "string_utils.h"
68
69namespace jami {
70
72
73constexpr const char* const Preferences::CONFIG_LABEL;
74const char* const Preferences::DFT_ZONE = "North America";
75const char* const Preferences::REGISTRATION_EXPIRE_KEY = "registrationexpire";
76constexpr std::string_view DEFAULT_CONFERENCE_RESOLUTION {"1280x720"};
77
78// general preferences
79static constexpr const char* ORDER_KEY {"order"};
80static constexpr const char* AUDIO_API_KEY {"audioApi"};
81static constexpr const char* HISTORY_LIMIT_KEY {"historyLimit"};
82static constexpr const char* RINGING_TIMEOUT {"ringingTimeout"};
83static constexpr const char* HISTORY_MAX_CALLS_KEY {"historyMaxCalls"};
84static constexpr const char* ZONE_TONE_CHOICE_KEY {"zoneToneChoice"};
85static constexpr const char* PORT_NUM_KEY {"portNum"};
86static constexpr const char* SEARCH_BAR_DISPLAY_KEY {"searchBarDisplay"};
87static constexpr const char* MD5_HASH_KEY {"md5Hash"};
88
89// voip preferences
90constexpr const char* const VoipPreference::CONFIG_LABEL;
91static constexpr const char* PLAY_DTMF_KEY {"playDtmf"};
92static constexpr const char* PLAY_TONES_KEY {"playTones"};
93static constexpr const char* PULSE_LENGTH_KEY {"pulseLength"};
94
95// audio preferences
96constexpr const char* const AudioPreference::CONFIG_LABEL;
97static constexpr const char* ALSAMAP_KEY {"alsa"};
98static constexpr const char* PULSEMAP_KEY {"pulse"};
99static constexpr const char* PORTAUDIO_KEY {"portaudio"};
100static constexpr const char* CARDIN_KEY {"cardIn"};
101static constexpr const char* CARDOUT_KEY {"cardOut"};
102static constexpr const char* CARLIBJAMI_KEY {"cardRing"};
103static constexpr const char* PLUGIN_KEY {"plugin"};
104static constexpr const char* SMPLRATE_KEY {"smplRate"};
105static constexpr const char* DEVICE_PLAYBACK_KEY {"devicePlayback"};
106static constexpr const char* DEVICE_RECORD_KEY {"deviceRecord"};
107static constexpr const char* DEVICE_RINGTONE_KEY {"deviceRingtone"};
108static constexpr const char* RECORDPATH_KEY {"recordPath"};
109static constexpr const char* ALWAYS_RECORDING_KEY {"alwaysRecording"};
110static constexpr const char* VOLUMEMIC_KEY {"volumeMic"};
111static constexpr const char* VOLUMESPKR_KEY {"volumeSpkr"};
112static constexpr const char* AUDIO_PROCESSOR_KEY {"audioProcessor"};
113static constexpr const char* NOISE_REDUCE_KEY {"noiseReduce"};
114static constexpr const char* AGC_KEY {"automaticGainControl"};
115static constexpr const char* CAPTURE_MUTED_KEY {"captureMuted"};
116static constexpr const char* PLAYBACK_MUTED_KEY {"playbackMuted"};
117static constexpr const char* VAD_KEY {"voiceActivityDetection"};
118static constexpr const char* ECHO_CANCEL_KEY {"echoCancel"};
119
120#ifdef ENABLE_VIDEO
121// video preferences
122constexpr const char* const VideoPreferences::CONFIG_LABEL;
123static constexpr const char* DECODING_ACCELERATED_KEY {"decodingAccelerated"};
124static constexpr const char* ENCODING_ACCELERATED_KEY {"encodingAccelerated"};
125static constexpr const char* RECORD_PREVIEW_KEY {"recordPreview"};
126static constexpr const char* RECORD_QUALITY_KEY {"recordQuality"};
127static constexpr const char* CONFERENCE_RESOLUTION_KEY {"conferenceResolution"};
128#endif
129
130#ifdef ENABLE_PLUGIN
131// plugin preferences
132constexpr const char* const PluginPreferences::CONFIG_LABEL;
133static constexpr const char* JAMI_PLUGIN_KEY {"pluginsEnabled"};
134static constexpr const char* JAMI_PLUGINS_INSTALLED_KEY {"installedPlugins"};
135static constexpr const char* JAMI_PLUGINS_LOADED_KEY {"loadedPlugins"};
136#endif
137
138static constexpr int PULSE_LENGTH_DEFAULT {250};
139#ifndef _MSC_VER
140static constexpr const char* ALSA_DFT_CARD {"0"};
141#else
142static constexpr const char* ALSA_DFT_CARD {"-1"};
143#endif // _MSC_VER
144
146 : accountOrder_("")
147 , historyLimit_(0)
148 , historyMaxCalls_(20)
149 , ringingTimeout_(30)
150 , zoneToneChoice_(DFT_ZONE) // DFT_ZONE
151 , portNum_(sip_utils::DEFAULT_SIP_PORT)
152 , searchBarDisplay_(true)
153 , md5Hash_(false)
154{}
155
156void
157Preferences::verifyAccountOrder(const std::vector<std::string>& accountIDs)
158{
159 std::vector<std::string> tokens;
160 std::string token;
161 bool drop = false;
162
163 for (const auto c : accountOrder_) {
164 if (c != '/') {
165 token += c;
166 } else {
167 if (find(accountIDs.begin(), accountIDs.end(), token) != accountIDs.end())
168 tokens.push_back(token);
169 else {
170 JAMI_DBG("Dropping nonexistent account %s", token.c_str());
171 drop = true;
172 }
173 token.clear();
174 }
175 }
176
177 if (drop) {
178 accountOrder_.clear();
179 for (const auto& t : tokens)
180 accountOrder_ += t + '/';
181 }
182}
183
184void
186{
187 // Add the newly created account in the account order list
188 if (not accountOrder_.empty())
189 accountOrder_.insert(0, newAccountID + "/");
190 else
191 accountOrder_ = newAccountID + "/";
192}
193
194void
196{
197 // include the slash since we don't want to remove a partial match
198 const size_t start = accountOrder_.find(oldAccountID + "/");
199 if (start != std::string::npos)
200 accountOrder_.erase(start, oldAccountID.length() + 1);
201}
202
203void
204Preferences::serialize(YAML::Emitter& out) const
205{
206 out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
207
208 out << YAML::Key << HISTORY_LIMIT_KEY << YAML::Value << historyLimit_;
209 out << YAML::Key << RINGING_TIMEOUT << YAML::Value << ringingTimeout_;
210 out << YAML::Key << HISTORY_MAX_CALLS_KEY << YAML::Value << historyMaxCalls_;
211 out << YAML::Key << MD5_HASH_KEY << YAML::Value << md5Hash_;
212 out << YAML::Key << ORDER_KEY << YAML::Value << accountOrder_;
213 out << YAML::Key << PORT_NUM_KEY << YAML::Value << portNum_;
214 out << YAML::Key << SEARCH_BAR_DISPLAY_KEY << YAML::Value << searchBarDisplay_;
215 out << YAML::Key << ZONE_TONE_CHOICE_KEY << YAML::Value << zoneToneChoice_;
216 out << YAML::EndMap;
217}
218
219void
220Preferences::unserialize(const YAML::Node& in)
221{
222 const auto& node = in[CONFIG_LABEL];
223
224 parseValue(node, ORDER_KEY, accountOrder_);
225 parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
226 parseValue(node, RINGING_TIMEOUT, ringingTimeout_);
227 parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
228 parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
229 parseValue(node, PORT_NUM_KEY, portNum_);
230 parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
231 parseValue(node, MD5_HASH_KEY, md5Hash_);
232}
233
235 : playDtmf_(true)
236 , playTones_(true)
237 , pulseLength_(PULSE_LENGTH_DEFAULT)
238{}
239
240void
241VoipPreference::serialize(YAML::Emitter& out) const
242{
243 out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
244 out << YAML::Key << PLAY_DTMF_KEY << YAML::Value << playDtmf_;
245 out << YAML::Key << PLAY_TONES_KEY << YAML::Value << playTones_;
246 out << YAML::Key << PULSE_LENGTH_KEY << YAML::Value << pulseLength_;
247 out << YAML::EndMap;
248}
249
250void
252{
253 const auto& node = in[CONFIG_LABEL];
254 parseValue(node, PLAY_DTMF_KEY, playDtmf_);
255 parseValue(node, PLAY_TONES_KEY, playTones_);
256 parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
257}
258
260 : audioApi_(PULSEAUDIO_API_STR)
261 , alsaCardin_(atoi(ALSA_DFT_CARD))
262 , alsaCardout_(atoi(ALSA_DFT_CARD))
263 , alsaCardRingtone_(atoi(ALSA_DFT_CARD))
264 , alsaPlugin_("default")
265 , alsaSmplrate_(44100)
266 , pulseDevicePlayback_("")
267 , pulseDeviceRecord_("")
268 , pulseDeviceRingtone_("")
269 , recordpath_("")
270 , alwaysRecording_(false)
271 , volumemic_(1.0)
272 , volumespkr_(1.0)
273 , audioProcessor_("webrtc")
274 , denoise_("auto")
275 , agcEnabled_(true)
276 , vadEnabled_(true)
277 , echoCanceller_("auto")
278 , captureMuted_(false)
279 , playbackMuted_(false)
280{}
281
282#if HAVE_ALSA
283
284static const int ALSA_DFT_CARD_ID = 0; // Index of the default soundcard
285
286static void
288{
290 JAMI_WARN(" Card with index %d doesn't exist or is unusable.", card);
292 }
293}
294#endif
295
296AudioLayer*
298{
299#if HAVE_OPENSL
300 return new OpenSLLayer(*this);
301#else
302
303#if HAVE_JACK
304 if (audioApi_ == JACK_API_STR) {
305 try {
306 if (auto ret = system("jack_lsp > /dev/null"))
307 throw std::runtime_error("Error running jack_lsp: " + std::to_string(ret));
308 return new JackLayer(*this);
309 } catch (const std::runtime_error& e) {
310 JAMI_ERR("%s", e.what());
311#if HAVE_PULSE
312 audioApi_ = PULSEAUDIO_API_STR;
313#elif HAVE_ALSA
314 audioApi_ = ALSA_API_STR;
315#elif HAVE_COREAUDIO
316 audioApi_ = COREAUDIO_API_STR;
317#elif HAVE_PORTAUDIO
318 audioApi_ = PORTAUDIO_API_STR;
319#else
320 throw;
321#endif // HAVE_PULSE
322 }
323 }
324#endif // HAVE_JACK
325
326#if HAVE_PULSE
327
328 if (audioApi_ == PULSEAUDIO_API_STR) {
329 try {
330 return new PulseLayer(*this);
331 } catch (const std::runtime_error& e) {
332 JAMI_WARN("Unable to create pulseaudio layer, falling back to ALSA");
333 }
334 }
335
336#endif
337
338#if HAVE_ALSA
339
340 audioApi_ = ALSA_API_STR;
343 checkSoundCard(alsaCardRingtone_, AudioDeviceType::RINGTONE);
344
345 return new AlsaLayer(*this);
346#endif
347
348#if HAVE_COREAUDIO
349 audioApi_ = COREAUDIO_API_STR;
350 try {
351 return new CoreLayer(*this);
352 } catch (const std::runtime_error& e) {
353 JAMI_WARN("Unable to create coreaudio layer. There will be no sound.");
354 }
355 return NULL;
356#endif
357
358#if HAVE_PORTAUDIO
359 audioApi_ = PORTAUDIO_API_STR;
360 try {
361 return new PortAudioLayer(*this);
362 } catch (const std::runtime_error& e) {
363 JAMI_WARN("Unable to create PortAudio layer. There will be no sound.");
364 }
365 return nullptr;
366#endif
367#endif // HAVE_OPENSL
368
369 JAMI_WARN("No audio layer provided");
370 return nullptr;
371}
372
373std::vector<std::string>
375{
376 return
377 {
378#if HAVE_OPENSL
380#endif
381#if HAVE_ALSA
383#endif
384#if HAVE_PULSE
386#endif
387#if HAVE_JACK
389#endif
390#if HAVE_COREAUDIO
392#endif
393#if HAVE_PORTAUDIO
395#endif
396 };
397}
398
399void
400AudioPreference::serialize(YAML::Emitter& out) const
401{
402 out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
403 // alsa submap
404 out << YAML::Key << ALSAMAP_KEY << YAML::Value << YAML::BeginMap;
405 out << YAML::Key << CARDIN_KEY << YAML::Value << alsaCardin_;
406 out << YAML::Key << CARDOUT_KEY << YAML::Value << alsaCardout_;
407 out << YAML::Key << CARLIBJAMI_KEY << YAML::Value << alsaCardRingtone_;
408 out << YAML::Key << PLUGIN_KEY << YAML::Value << alsaPlugin_;
409 out << YAML::Key << SMPLRATE_KEY << YAML::Value << alsaSmplrate_;
410 out << YAML::EndMap;
411
412 // common options
413 out << YAML::Key << ALWAYS_RECORDING_KEY << YAML::Value << alwaysRecording_;
414 out << YAML::Key << AUDIO_API_KEY << YAML::Value << audioApi_;
415 out << YAML::Key << CAPTURE_MUTED_KEY << YAML::Value << captureMuted_;
416 out << YAML::Key << PLAYBACK_MUTED_KEY << YAML::Value << playbackMuted_;
417
418 // pulse submap
419 out << YAML::Key << PULSEMAP_KEY << YAML::Value << YAML::BeginMap;
420 out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << pulseDevicePlayback_;
421 out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << pulseDeviceRecord_;
422 out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << pulseDeviceRingtone_;
423 out << YAML::EndMap;
424
425 // portaudio submap
426 out << YAML::Key << PORTAUDIO_KEY << YAML::Value << YAML::BeginMap;
427 out << YAML::Key << DEVICE_PLAYBACK_KEY << YAML::Value << portaudioDevicePlayback_;
428 out << YAML::Key << DEVICE_RECORD_KEY << YAML::Value << portaudioDeviceRecord_;
429 out << YAML::Key << DEVICE_RINGTONE_KEY << YAML::Value << portaudioDeviceRingtone_;
430 out << YAML::EndMap;
431
432 // more common options!
433 out << YAML::Key << RECORDPATH_KEY << YAML::Value << recordpath_;
434 out << YAML::Key << VOLUMEMIC_KEY << YAML::Value << volumemic_;
435 out << YAML::Key << VOLUMESPKR_KEY << YAML::Value << volumespkr_;
436
437 // audio processor options, not in a submap
438 out << YAML::Key << AUDIO_PROCESSOR_KEY << YAML::Value << audioProcessor_;
439 out << YAML::Key << AGC_KEY << YAML::Value << agcEnabled_;
440 out << YAML::Key << VAD_KEY << YAML::Value << vadEnabled_;
441 out << YAML::Key << NOISE_REDUCE_KEY << YAML::Value << denoise_;
442 out << YAML::Key << ECHO_CANCEL_KEY << YAML::Value << echoCanceller_;
443 out << YAML::EndMap;
444}
445
446bool
448{
449 std::string path = fileutils::expand_path(r);
451 recordpath_ = path;
452 return true;
453 } else {
454 JAMI_ERR("%s is not writable, unable to be the recording path", path.c_str());
455 return false;
456 }
457}
458
459void
461{
462 const auto& node = in[CONFIG_LABEL];
463
464 // alsa submap
465 const auto& alsa = node[ALSAMAP_KEY];
466
467 parseValue(alsa, CARDIN_KEY, alsaCardin_);
468 parseValue(alsa, CARDOUT_KEY, alsaCardout_);
469 parseValue(alsa, CARLIBJAMI_KEY, alsaCardRingtone_);
470 parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
471 parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);
472
473 // common options
474 parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
475 parseValue(node, AUDIO_API_KEY, audioApi_);
476 parseValue(node, AGC_KEY, agcEnabled_);
477 parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
478 parseValue(node, NOISE_REDUCE_KEY, denoise_);
479 parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);
480
481 // pulse submap
482 const auto& pulse = node[PULSEMAP_KEY];
483 parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
484 parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
485 parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);
486
487 // portaudio submap
488 const auto& portaudio = node[PORTAUDIO_KEY];
489 parseValue(portaudio, DEVICE_PLAYBACK_KEY, portaudioDevicePlayback_);
490 parseValue(portaudio, DEVICE_RECORD_KEY, portaudioDeviceRecord_);
491 parseValue(portaudio, DEVICE_RINGTONE_KEY, portaudioDeviceRingtone_);
492
493 // more common options!
494 parseValue(node, RECORDPATH_KEY, recordpath_);
495 parseValue(node, VOLUMEMIC_KEY, volumemic_);
496 parseValue(node, VOLUMESPKR_KEY, volumespkr_);
497 parseValue(node, AUDIO_PROCESSOR_KEY, audioProcessor_);
498 parseValue(node, VAD_KEY, vadEnabled_);
499 parseValue(node, ECHO_CANCEL_KEY, echoCanceller_);
500}
501
502#ifdef ENABLE_VIDEO
503VideoPreferences::VideoPreferences()
507 , recordQuality_(0)
509{}
510
511void
512VideoPreferences::serialize(YAML::Emitter& out) const
513{
514 out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
515 out << YAML::Key << RECORD_PREVIEW_KEY << YAML::Value << recordPreview_;
516 out << YAML::Key << RECORD_QUALITY_KEY << YAML::Value << recordQuality_;
517#ifdef RING_ACCEL
518 out << YAML::Key << DECODING_ACCELERATED_KEY << YAML::Value << decodingAccelerated_;
519 out << YAML::Key << ENCODING_ACCELERATED_KEY << YAML::Value << encodingAccelerated_;
520#endif
521 out << YAML::Key << CONFERENCE_RESOLUTION_KEY << YAML::Value << conferenceResolution_;
522 if (auto dm = getVideoDeviceMonitor())
523 dm->serialize(out);
524 out << YAML::EndMap;
525}
526
527void
528VideoPreferences::unserialize(const YAML::Node& in)
529{
530 // values may or may not be present
531 const auto& node = in[CONFIG_LABEL];
532 try {
535 } catch (...) {
536 recordPreview_ = true;
537 recordQuality_ = 0;
538 }
539#ifdef RING_ACCEL
540 try {
543 } catch (...) {
545 encodingAccelerated_ = false;
546 }
547#endif
548 try {
550 } catch (...) {
552 }
553 if (auto dm = getVideoDeviceMonitor())
554 dm->unserialize(in);
555}
556#endif // ENABLE_VIDEO
557
558#ifdef ENABLE_PLUGIN
559PluginPreferences::PluginPreferences()
561{}
562
563void
564PluginPreferences::serialize(YAML::Emitter& out) const
565{
566 out << YAML::Key << CONFIG_LABEL << YAML::Value << YAML::BeginMap;
567 out << YAML::Key << JAMI_PLUGIN_KEY << YAML::Value << pluginsEnabled_;
568 out << YAML::Key << JAMI_PLUGINS_INSTALLED_KEY << YAML::Value << installedPlugins_;
569 out << YAML::Key << JAMI_PLUGINS_LOADED_KEY << YAML::Value << loadedPlugins_;
570 out << YAML::EndMap;
571}
572
573void
574PluginPreferences::unserialize(const YAML::Node& in)
575{
576 // values may or may not be present
577 const auto& node = in[CONFIG_LABEL];
578 try {
580 } catch (...) {
581 pluginsEnabled_ = false;
582 }
583
585 try {
587 } catch (...) {
588 }
589
590 const auto& loadedPluginsNode = node[JAMI_PLUGINS_LOADED_KEY];
591 try {
593 } catch (...) {
594 // loadedPlugins_ = {};
595 }
596}
597#endif // ENABLE_PLUGIN
598
599} // namespace jami
Main sound class.
#define ALSA_API_STR
Definition audiolayer.h:44
#define OPENSL_API_STR
Definition audiolayer.h:42
#define PULSEAUDIO_API_STR
Definition audiolayer.h:43
#define JACK_API_STR
Definition audiolayer.h:45
#define PORTAUDIO_API_STR
Definition audiolayer.h:47
#define COREAUDIO_API_STR
Definition audiolayer.h:46
static bool soundCardIndexExists(int card, AudioDeviceType stream)
Check if the given index corresponds to an existing sound card and supports the specified streaming m...
AudioLayer * createAudioLayer()
bool setRecordPath(const std::string &r)
void unserialize(const YAML::Node &in) override
static std::vector< std::string > getSupportedAudioManagers()
void serialize(YAML::Emitter &out) const override
void verifyAccountOrder(const std::vector< std::string > &accounts)
static const char *const DFT_ZONE
Definition preferences.h:44
void removeAccount(const std::string &acc)
void unserialize(const YAML::Node &in) override
void serialize(YAML::Emitter &out) const override
Preferences()
Default sound card index.
static const char *const REGISTRATION_EXPIRE_KEY
Definition preferences.h:45
void addAccount(const std::string &acc)
void serialize(YAML::Emitter &out) const override
void unserialize(const YAML::Node &in) override
#define JAMI_ERR(...)
Definition logger.h:218
#define JAMI_DBG(...)
Definition logger.h:216
#define JAMI_WARN(...)
Definition logger.h:217
bool isDirectoryWritable(const std::string &directory)
std::string expand_path(const std::string &path)
Expand the given path.
void parseValue(const YAML::Node &node, const char *key, T &value)
Definition yamlparser.h:31
std::set< std::string > parseVector(const YAML::Node &node)
static constexpr const char * CARDIN_KEY
static constexpr const char * RECORDPATH_KEY
static constexpr const char * VOLUMEMIC_KEY
static constexpr const char * CARLIBJAMI_KEY
static constexpr const char * NOISE_REDUCE_KEY
static constexpr const char * AGC_KEY
void emitSignal(Args... args)
Definition ring_signal.h:64
static constexpr const char * AUDIO_API_KEY
static constexpr const char * CAPTURE_MUTED_KEY
static constexpr const char * PLAY_DTMF_KEY
static constexpr const char * RINGING_TIMEOUT
static constexpr const char * DEVICE_RECORD_KEY
constexpr std::string_view DEFAULT_CONFERENCE_RESOLUTION
static constexpr const char * ECHO_CANCEL_KEY
static constexpr const char * HISTORY_MAX_CALLS_KEY
static constexpr const char * SMPLRATE_KEY
static constexpr const char * PLAYBACK_MUTED_KEY
static constexpr const char * CARDOUT_KEY
static constexpr const char * MD5_HASH_KEY
static constexpr const char * ALWAYS_RECORDING_KEY
static constexpr const char * HISTORY_LIMIT_KEY
static constexpr const char * DEVICE_RINGTONE_KEY
static constexpr const char * ALSAMAP_KEY
static constexpr const char * PLAY_TONES_KEY
static constexpr const char * ORDER_KEY
static constexpr int PULSE_LENGTH_DEFAULT
static constexpr const char * VAD_KEY
static constexpr const char * SEARCH_BAR_DISPLAY_KEY
static constexpr const char * VOLUMESPKR_KEY
static constexpr const char * PLUGIN_KEY
static constexpr const char * DEVICE_PLAYBACK_KEY
static constexpr const char * PORTAUDIO_KEY
static constexpr const char * ALSA_DFT_CARD
Default DTMF length.
AudioDeviceType
Definition audiolayer.h:58
static constexpr const char * AUDIO_PROCESSOR_KEY
static constexpr const char * PULSEMAP_KEY
static constexpr const char * PULSE_LENGTH_KEY
static constexpr const char * PORT_NUM_KEY
static constexpr const char * ZONE_TONE_CHOICE_KEY