swift
afvclient.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2019 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_CORE_AFV_CLIENTS_AFVCLIENT_H
7 #define SWIFT_CORE_AFV_CLIENTS_AFVCLIENT_H
8 
9 #include <atomic>
10 
11 #include <QObject>
12 #include <QString>
13 #include <QVector>
14 
15 #include "core/afv/audio/input.h"
16 #include "core/afv/audio/output.h"
19 #include "core/afv/dto.h"
21 #include "core/swiftcoreexport.h"
25 #include "misc/identifiable.h"
26 #include "misc/settingscache.h"
27 #include "misc/worker.h"
29 
30 namespace swift::core::afv::clients
31 {
34  {
35  Q_OBJECT
36 
39  Q_PROPERTY(double inputVolumePeakVU READ getInputVolumePeakVU NOTIFY inputVolumePeakVU)
40  Q_PROPERTY(double outputVolumePeakVU READ getOutputVolumePeakVU NOTIFY outputVolumePeakVU)
41  Q_PROPERTY(swift::core::afv::clients::CAfvClient::ConnectionStatus connectionStatus READ getConnectionStatus
42  NOTIFY connectionStatusChanged)
43  Q_PROPERTY(QString receivingCallsignsCom1 READ getReceivingCallsignsStringCom1 NOTIFY receivingCallsignsChanged)
44  Q_PROPERTY(QString receivingCallsignsCom2 READ getReceivingCallsignsStringCom2 NOTIFY receivingCallsignsChanged)
46 
47  public:
49  static const QStringList &getLogCategories();
50 
53  {
54  Disconnected,
55  Connected
56  };
57  Q_ENUM(ConnectionStatus)
58 
59 
60  CAfvClient(const QString &apiServer, QObject *owner);
61 
63  ~CAfvClient() override { this->stopAudio(); }
64 
67  CAfvClient(const CAfvClient &) = delete;
68  CAfvClient &operator=(const CAfvClient &) = delete;
70 
73  CAfvClient(const CAfvClient &&) = delete;
74  CAfvClient &operator=(const CAfvClient &&) = delete;
76 
80  QString getCallsign() const;
81  void setCallsign(const QString &getCallsign);
83 
86  bool isConnected() const;
87 
90  ConnectionStatus getConnectionStatus() const;
91 
95  Q_INVOKABLE void connectTo(const QString &cid, const QString &password, const QString &callsign,
96  const QString &client);
97 
102  void disconnectFrom(bool stop);
103  Q_INVOKABLE void disconnectFrom() { this->disconnectFrom(false); }
104  void disconnectFromAndStop() { this->disconnectFrom(true); }
106 
109  Q_INVOKABLE QStringList availableInputDevices() const;
110  Q_INVOKABLE QStringList availableOutputDevices() const;
112 
114  Q_INVOKABLE void setBypassEffects(bool value);
115 
117  bool isStarted() const { return m_isStarted; }
118 
122  bool isOutputMuted() const;
123  void setOutputMuted(bool mute);
125 
128  void startAudio();
129  void startAudio(const swift::misc::audio::CAudioDeviceInfo &inputDevice,
130  const swift::misc::audio::CAudioDeviceInfo &outputDevice);
131  Q_INVOKABLE void startAudio(const QString &inputDeviceName, const QString &outputDeviceName);
132  void stopAudio();
133  void restartAudio();
135 
138  bool isComUnitIntegrated() const { return m_integratedComUnit; }
139 
140  /* NOT used
143  double getDeviceInputVolume() const;
144  bool setDeviceInputVolume(double volume);
145  double getDeviceOutputVolume() const;
146  bool setDeviceOutputVolume(double volume);
148  */
149 
152  void setReceiveAudio(bool receive);
153 
157  Q_INVOKABLE void enableTransceiver(quint16 id, bool enable);
158  void enableComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit, bool enable);
159  bool isEnabledTransceiver(quint16 id) const;
160  bool isEnabledComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit) const;
162 
166  void setTransmittingTransceiver(quint16 transceiverID);
167  void setTransmittingComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit);
168  void setTransmittingTransceivers(const QVector<TxTransceiverDto> &transceivers);
170 
174  bool isTransmittingTransceiver(quint16 id) const;
175  bool isTransmittingComUnit(swift::misc::aviation::CComSystem::ComUnit comUnit) const;
177 
181  void setRxTx(bool rx1, bool tx1, bool rx2, bool tx2);
182  void getRxTx(bool &rx1, bool &tx1, bool &rx2, bool &tx2) const;
184 
188  QVector<TransceiverDto> getTransceivers() const;
189  QVector<TxTransceiverDto> getTransmittingTransceivers() const;
190  QSet<quint16> getEnabledTransceivers() const;
192 
196  Q_INVOKABLE void updateComFrequency(quint16 id, quint32 frequencyHz);
197  void updateComFrequency(swift::misc::aviation::CComSystem::ComUnit comUnit,
199  void updateComFrequency(swift::misc::aviation::CComSystem::ComUnit comUnit,
200  const swift::misc::aviation::CComSystem &comSystem);
202 
205  Q_INVOKABLE void updatePosition(double latitudeDeg, double longitudeDeg, double heightMeters);
206 
210  void updateFromOwnAircraft(const swift::misc::simulation::CSimulatedAircraft &aircraft,
211  bool withSignals = true);
212 
215  Q_INVOKABLE void setPtt(bool active);
216 
220  Q_INVOKABLE void setLoopBack(bool on) { m_loopbackOn = on; }
221  Q_INVOKABLE bool isLoopback() const { return m_loopbackOn; }
223 
227  double getInputVolumeDb() const;
228  Q_INVOKABLE bool setInputVolumeDb(double valueDb);
230 
234  double getComOutputVolumeDb(swift::misc::aviation::CComSystem::ComUnit comUnit) const;
235  Q_INVOKABLE bool setComOutputVolumeDb(swift::misc::aviation::CComSystem::ComUnit comUnit, double valueDb);
237 
240  double getOutputGainRatio(swift::misc::aviation::CComSystem::ComUnit comUnit) const;
241 
245  int getNormalizedInputVolume() const;
246  int getNormalizedComOutputVolume(swift::misc::aviation::CComSystem::ComUnit comUnit) const;
247  int getNormalizedMasterOutputVolume() const;
248  bool setNormalizedInputVolume(int volume);
249  bool setNormalizedComOutputVolume(swift::misc::aviation::CComSystem::ComUnit comUnit, int volume);
250  bool setNormalizedMasterOutputVolume(int volume);
252 
256  double getInputVolumePeakVU() const;
257  double getOutputVolumePeakVU() const;
259 
263  const swift::misc::audio::CAudioDeviceInfo &getInputDevice() const;
264  const swift::misc::audio::CAudioDeviceInfo &getOutputDevice() const;
265  bool usesSameDevices(const swift::misc::audio::CAudioDeviceInfo &inputDevice,
266  const swift::misc::audio::CAudioDeviceInfo &outputDevice);
268 
272  QString getReceivingCallsignsStringCom1() const;
273  QString getReceivingCallsignsStringCom2() const;
274  swift::misc::aviation::CCallsignSet getReceivingCallsignsCom1() const;
275  swift::misc::aviation::CCallsignSet getReceivingCallsignsCom2() const;
276  QStringList getReceivingCallsignsStringCom1Com2() const;
278 
280  bool updateVoiceServerUrl(const QString &url);
281 
283  void gracefulShutdown();
284 
285  signals:
289 
293  const swift::misc::aviation::CCallsignSet &com2Callsigns);
294 
297 
300 
303 
305  void ptt(bool active, const swift::misc::CIdentifier &identifier);
306 
309  void inputVolumePeakVU(double value);
310  void outputVolumePeakVU(double value);
312 
315  const swift::misc::audio::CAudioDeviceInfo &outputDevice);
316 
318  void stoppedAudio();
319 
321  void changedOutputMute(bool muted);
322 
323  protected:
325  void initialize() override;
326 
328  void cleanup() override;
329 
330  private:
331  void opusDataAvailable(const audio::OpusDataAvailableArgs &args); // threadsafe
332  void audioOutDataAvailable(const AudioRxOnTransceiversDto &dto); // threadsafe
333  void inputVolumeStream(const audio::InputVolumeStreamArgs &args);
334  void outputVolumeStream(const audio::OutputVolumeStreamArgs &args);
335 
336  void onTimerUpdate();
337  void onSettingsChanged();
338  void autoLogoffWithoutFsdNetwork();
339 
340  void updateTransceivers(bool updateFrequencies = true);
341  void onUpdateTransceiversFromContext(const swift::misc::simulation::CSimulatedAircraft &aircraft,
342  const swift::misc::CIdentifier &originator);
343  void onReceivingCallsignsChanged(const swift::core::afv::audio::TransceiverReceivingCallsignsChangedArgs &args);
344 
346  void retryConnectTo(const QString &cid, const QString &password, const QString &callsign, const QString &client,
347  const QString &reason);
348 
350  void reconnectTo(const QString &cid, const QString &password, const QString &callsign, const QString &client,
351  int delayMs, const swift::misc::CStatusMessage &msg);
352 
355  void toggleTransmissionCapability(bool disableTransmission);
356 
360  QVector<StationDto> getAliasedStations() const;
361  void setAliasedStations(const QVector<StationDto> &stations);
363 
366  quint32 getAliasFrequencyHz(quint32 frequencyHz) const;
367 
370  bool isVoiceServerAlive() const;
371 
374  const QString &getVoiceServerUrl() const;
375 
376  bool fuzzyMatchCallsign(const QString &callsign, const QString &compareTo) const;
377  void getPrefixSuffix(const QString &callsign, QString &prefix, QString &suffix) const;
378 
379  static constexpr int PositionUpdatesMs = 20000;
380  static constexpr int SampleRate = 48000;
381  static constexpr int FrameSize = static_cast<int>(SampleRate * 0.02);
382  static constexpr double MinDbIn = -18.0;
383  static constexpr double MaxDbIn = 18.0;
384  static constexpr double MinDbOut = -60.0;
385  static constexpr double MaxDbOut = 18.0;
386  static constexpr quint32 UniCom = 122800000;
387 
388  static quint16 comUnitToTransceiverId(swift::misc::aviation::CComSystem::ComUnit comUnit);
389  static swift::misc::aviation::CComSystem::ComUnit transceiverIdToComUnit(quint16 id);
390 
391  connection::CClientConnection *m_connection = nullptr;
392  swift::misc::CSetting<swift::misc::audio::TSettings> m_audioSettings { this, &CAfvClient::onSettingsChanged };
393  QString m_callsign;
394 
395  audio::CInput *m_input = nullptr;
396  audio::COutput *m_output = nullptr;
397 
398  audio::CSoundcardSampleProvider *m_soundcardSampleProvider = nullptr;
399  swift::sound::sample_provider::CVolumeSampleProvider *m_outputSampleProvider = nullptr;
400 
401  std::atomic_bool m_transmit { false };
402  std::atomic_bool m_transmitHistory { false };
403  std::atomic_bool m_disableTransmissionCapability { false };
404  QVector<TxTransceiverDto> m_transmittingTransceivers;
405  QVector<TransceiverDto> m_transceivers;
406  QSet<quint16> m_enabledTransceivers;
407  static const QVector<quint16> &allTransceiverIds()
408  {
409  static const QVector<quint16> transceiverIds { 0, 1 };
410  return transceiverIds;
411  }
412 
413  std::atomic_int m_fsdConnectMismatches { 0 };
414  std::atomic_int m_retryConnectAttempt { 0 };
415  std::atomic_int m_heartBeatFailures { 0 };
416  std::atomic_bool m_isStarted { false };
417  std::atomic_bool m_loopbackOn { false };
418  std::atomic_bool m_winCoInitialized { false };
419  std::atomic_bool m_integratedComUnit { false };
420 
421  double m_inputVolumeDb = 0.0;
422  int m_outputMasterVolumeNormalized = 0;
423  int m_outputVolumeCom1Normalized = 0;
424  int m_outputVolumeCom2Normalized = 0;
425  double m_outputVolumeDbCom1 = 0.0;
426  double m_outputGainRatioCom1 = 1.0;
427  double m_outputVolumeDbCom2 = 0.0;
428  double m_outputGainRatioCom2 = 1.0;
429  double m_maxDbReadingInPTTInterval = -100;
430 
431  QTimer *m_voiceServerTimer = nullptr;
432  QVector<StationDto> m_aliasedStations;
433 
434  audio::InputVolumeStreamArgs m_inputVolumeStream;
435  audio::OutputVolumeStreamArgs m_outputVolumeStream;
436 
437  void checkServerHeartbeat();
438  void deferredInit();
439  void initTransceivers();
440  void connectWithContexts();
441  void fetchSimulatorSettings();
442  static bool hasContexts();
443 
444  std::atomic_bool m_connectedWithContext { false };
445 
446  mutable QRecursiveMutex m_mutex;
447  mutable QRecursiveMutex m_mutexInputStream;
448  mutable QRecursiveMutex m_mutexOutputStream;
449  mutable QRecursiveMutex m_mutexTransceivers;
450  mutable QRecursiveMutex m_mutexCallsign;
451  mutable QRecursiveMutex m_mutexConnection;
452  mutable QRecursiveMutex m_mutexVolume;
453  mutable QRecursiveMutex m_mutexSampleProviders;
454  };
455 } // namespace swift::core::afv::clients
456 
457 #endif // SWIFT_CORE_AFV_CLIENTS_AFVCLIENT_H
void ptt(bool active, const swift::misc::CIdentifier &identifier)
PTT status in this particular AFV client.
CAfvClient(const CAfvClient &)=delete
Copy operations.
void changedOutputMute(bool muted)
Output mute changed.
ConnectionStatus
Connection status.
Definition: afvclient.h:53
CAfvClient & operator=(const CAfvClient &&)=delete
Copy operations.
Q_INVOKABLE bool isLoopback() const
Loopback.
Definition: afvclient.h:221
void updatedFromOwnAircraftCockpit()
Client updated from own aicraft data.
void afvConnectionFailure(const swift::misc::CStatusMessage &msg)
Authentication has failed with AFV server.
CAfvClient & operator=(const CAfvClient &)=delete
Copy operations.
void stoppedAudio()
Audio has been stopped.
CAfvClient(const CAfvClient &&)=delete
}@
Q_INVOKABLE void disconnectFrom()
Disconnect from network.
Definition: afvclient.h:103
void startedAudio(const swift::misc::audio::CAudioDeviceInfo &inputDevice, const swift::misc::audio::CAudioDeviceInfo &outputDevice)
Started audio with devices.
bool isStarted() const
Client started?
Definition: afvclient.h:117
void receivedCallsignsChanged(const swift::misc::aviation::CCallsignSet &com1Callsigns, const swift::misc::aviation::CCallsignSet &com2Callsigns)
Received callsigns have been changed.
void outputVolumePeakVU(double value)
VU levels.
void inputVolumePeakVU(double value)
VU levels.
void connectionStatusChanged(ConnectionStatus status)
Connection status has been changed.
Q_INVOKABLE void setLoopBack(bool on)
Loopback.
Definition: afvclient.h:220
void receivingCallsignsChanged(const swift::core::afv::audio::TransceiverReceivingCallsignsChangedArgs &args)
Receiving callsigns have been changed.
bool isComUnitIntegrated() const
Is integrated with COM unit.
Definition: afvclient.h:138
void disconnectFromAndStop()
Disconnect from network.
Definition: afvclient.h:104
Base class for a long-lived worker object which lives in its own thread.
Definition: worker.h:275
Base class with a member CIdentifier to be inherited by a class which has an identity in the environm...
Definition: identifiable.h:24
Value object encapsulating information identifying a component of a modular distributed swift process...
Definition: identifier.h:29
Streamable status message, e.g.
Value object encapsulating information of a audio device.
Value object for a set of callsigns.
Definition: callsignset.h:26
COM system (aka "radio")
Definition: comsystem.h:37
Comprehensive information of an aircraft.
AudioRxOnTransceiversDto.
Definition: dto.h:256
Input volume stream arguments.
Definition: input.h:62
#define SWIFT_CORE_EXPORT
Export a class or function from the library.