mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-28 11:45:40 +08:00
committed by
Mathew Sutcliffe
parent
51cbd2a394
commit
1c1fdabd2e
283
src/blackcore/voice_vatlib.h
Normal file
283
src/blackcore/voice_vatlib.h
Normal file
@@ -0,0 +1,283 @@
|
||||
/* Copyright (C) 2013 VATSIM Community / authors
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BLACKCORE_VOICE_VATLIB_H
|
||||
#define BLACKCORE_VOICE_VATLIB_H
|
||||
|
||||
#include "voice.h"
|
||||
#include "../blackmisc/vaudiodevicelist.h"
|
||||
#include "../blackmisc/nwuserlist.h"
|
||||
#include <QScopedPointer>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
/*!
|
||||
* Vatlib implementation of the IVoiceClient interface.
|
||||
*/
|
||||
class CVoiceVatlib : public IVoice
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Constructor
|
||||
* \param parent
|
||||
*/
|
||||
CVoiceVatlib(QObject *parent = nullptr);
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
*/
|
||||
virtual ~CVoiceVatlib();
|
||||
|
||||
// Hardware devices
|
||||
// TODO: Vatlib supports multiple output devices. That basically means, you could connect
|
||||
// to different voice rooms and send their audio to different devices, e.g. ATIS to loudspeakers
|
||||
// and ATC to headspeakers. Is not important to implement that now, if ever.
|
||||
virtual const BlackMisc::Voice::CAudioDeviceList &audioDevices() const ;
|
||||
virtual const BlackMisc::Voice::CAudioDevice defaultAudioInputDevice() const;
|
||||
virtual const BlackMisc::Voice::CAudioDevice defaultAudioOutputDevice() const;
|
||||
virtual void setInputDevice(const BlackMisc::Voice::CAudioDevice &device);
|
||||
virtual void setOutputDevice(const BlackMisc::Voice::CAudioDevice &device);
|
||||
|
||||
/************************************************
|
||||
* SETUP TESTS
|
||||
* *********************************************/
|
||||
|
||||
// Mic tests
|
||||
virtual void runSquelchTest();
|
||||
virtual void runMicTest();
|
||||
|
||||
virtual float inputSquelch() const;
|
||||
virtual int32_t micTestResult() const;
|
||||
virtual QString micTestResultAsString() const;
|
||||
|
||||
|
||||
public slots:
|
||||
/*!
|
||||
* \brief ATC station callsign, used for voice room designator
|
||||
* \param callsign
|
||||
*/
|
||||
virtual void setMyAircraftCallsign(const BlackMisc::Aviation::CCallsign &callsign);
|
||||
|
||||
/*!
|
||||
* \brief Join a given voice room
|
||||
* \param comUnit
|
||||
* \param voiceRoom
|
||||
*/
|
||||
virtual void joinVoiceRoom(const ComUnit comUnit, const BlackMisc::Voice::CVoiceRoom &voiceRoom);
|
||||
|
||||
/*!
|
||||
* \brief Leave voice room
|
||||
* \param comUnit
|
||||
*/
|
||||
virtual void leaveVoiceRoom(const ComUnit comUnit);
|
||||
|
||||
/*!
|
||||
* \brief Leave all voice rooms
|
||||
*/
|
||||
virtual void leaveAllVoiceRooms();
|
||||
|
||||
/*!
|
||||
* \brief Room output volume as per COM unit
|
||||
* \param comUnit
|
||||
* \param volumne
|
||||
*/
|
||||
virtual void setRoomOutputVolume(const ComUnit comUnit, const int32_t volumne);
|
||||
|
||||
/*!
|
||||
* \brief Start transmitting ("talk")
|
||||
* \param comUnit
|
||||
*/
|
||||
virtual void startTransmitting(const ComUnit comUnit);
|
||||
|
||||
/*!
|
||||
* \brief Stop transmitting ("talk")
|
||||
* \param comUnit
|
||||
*/
|
||||
virtual void stopTransmitting(const ComUnit comUnit);
|
||||
|
||||
/*!
|
||||
* Get COM1/2 voice rooms, which then allows to retrieve information
|
||||
* such as connection status etc.
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Voice::CVoiceRoomList getComVoiceRoomsWithAudioStatus();
|
||||
|
||||
/*!
|
||||
* \brief Voice rooms, const version with no updates
|
||||
* \return
|
||||
*/
|
||||
virtual BlackMisc::Voice::CVoiceRoomList getComVoiceRooms() const
|
||||
{
|
||||
return this->m_voiceRooms;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Get voice room callsings
|
||||
* \param comUnit
|
||||
* \return
|
||||
*/
|
||||
virtual QSet<QString> getVoiceRoomCallsings(const ComUnit comUnit) const
|
||||
{
|
||||
if (!this->m_voiceRoomCallsigns.contains(comUnit)) return QSet<QString>();
|
||||
return this->m_voiceRoomCallsigns[comUnit];
|
||||
}
|
||||
|
||||
/************************************************
|
||||
* NON API METHODS:
|
||||
* The following methods are not part of the
|
||||
* public API. They are needed for internal
|
||||
* workflow.
|
||||
* *********************************************/
|
||||
|
||||
int32_t queryUserRoomIndex() const {return m_queryUserRoomIndex;}
|
||||
|
||||
void changeRoomStatus(ComUnit comUnit, Cvatlib_Voice_Simple::roomStatusUpdate upd);
|
||||
|
||||
signals:
|
||||
|
||||
/*!
|
||||
* \brief User joined or left
|
||||
* \param comUnit
|
||||
*/
|
||||
void userJoinedLeft(const ComUnit comUnit);
|
||||
|
||||
protected: // QObject overrides
|
||||
|
||||
/*!
|
||||
* \brief Process voice lib
|
||||
*/
|
||||
virtual void timerEvent(QTimerEvent *);
|
||||
|
||||
private slots:
|
||||
// slots for Mic tests
|
||||
void onEndFindSquelch();
|
||||
void onEndMicTest();
|
||||
|
||||
// slot to handle users
|
||||
void onUserJoinedLeft(const ComUnit comUnit);
|
||||
|
||||
private:
|
||||
|
||||
// shimlib callbacks
|
||||
static void onRoomStatusUpdate(Cvatlib_Voice_Simple *obj, Cvatlib_Voice_Simple::roomStatusUpdate upd, int32_t roomIndex, void *cbVar);
|
||||
static void onRoomUserReceived(Cvatlib_Voice_Simple *obj, const char *name, void *cbVar);
|
||||
static void onInputHardwareDeviceReceived(Cvatlib_Voice_Simple *obj, const char *name, void *cbVar);
|
||||
static void onOutputHardwareDeviceReceived(Cvatlib_Voice_Simple *obj, const char *name, void *cbVar);
|
||||
|
||||
BlackMisc::Voice::CVoiceRoom voiceRoomForUnit(const ComUnit comUnit) const;
|
||||
void setVoiceRoomForUnit(const IVoice::ComUnit comUnit, const BlackMisc::Voice::CVoiceRoom &voiceRoom);
|
||||
void addUserInRoom(const ComUnit comUnit, const QString &callsign);
|
||||
void removeUserFromRoom(const ComUnit comUnit, const QString &callsign);
|
||||
void exceptionDispatcher(const char *caller);
|
||||
void enableAudio(const ComUnit comUnit);
|
||||
void handlePushToTalk();
|
||||
|
||||
/*!
|
||||
* \brief Deleter
|
||||
*/
|
||||
struct Cvatlib_Voice_Simple_Deleter
|
||||
{
|
||||
/*!
|
||||
* \brief Cleanup
|
||||
* \param pointer
|
||||
*/
|
||||
static inline void cleanup(Cvatlib_Voice_Simple *pointer)
|
||||
{
|
||||
pointer->Destroy();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
/*!
|
||||
* \brief Keyboard PTT handling class
|
||||
*/
|
||||
class CKeyboard
|
||||
{
|
||||
public:
|
||||
// Keyboard hook
|
||||
static HHOOK s_keyboardHook;
|
||||
static CVoiceVatlib *s_voice;
|
||||
static LRESULT CALLBACK keyboardProcedure(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
/*!
|
||||
* \brief Constructor, keyboard handling
|
||||
*/
|
||||
CKeyboard(CVoiceVatlib *vatlib)
|
||||
{
|
||||
CVoiceVatlib::CKeyboard::s_voice = vatlib;
|
||||
CVoiceVatlib::CKeyboard::s_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, CVoiceVatlib::CKeyboard::keyboardProcedure, GetModuleHandle(NULL), 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~CKeyboard()
|
||||
{
|
||||
if (!CVoiceVatlib::CKeyboard::s_keyboardHook) return;
|
||||
UnhookWindowsHookEx(CVoiceVatlib::CKeyboard::s_keyboardHook);
|
||||
CVoiceVatlib::CKeyboard::s_keyboardHook = nullptr;
|
||||
CVoiceVatlib::CKeyboard::s_voice = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
/*!
|
||||
* \brief Keyboard PTT handling class
|
||||
*/
|
||||
class CKeyboard
|
||||
{
|
||||
public:
|
||||
static CVoiceVatlib *s_voice;
|
||||
|
||||
/*!
|
||||
* \brief Constructor, keyboard handling
|
||||
*/
|
||||
CKeyboard(CVoiceVatlib *vatlib)
|
||||
{
|
||||
CVoiceVatlib::CKeyboard::s_voice = vatlib;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destructor
|
||||
*/
|
||||
~CKeyboard()
|
||||
{
|
||||
// void
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
QScopedPointer<Cvatlib_Voice_Simple, Cvatlib_Voice_Simple_Deleter> m_voice;
|
||||
BlackMisc::Aviation::CCallsign m_aircraftCallsign; /*!< own callsign to join voice rooms */
|
||||
BlackMisc::Voice::CVoiceRoomList m_voiceRooms;
|
||||
BlackMisc::Voice::CAudioDeviceList m_devices; /*!< in and output devices */
|
||||
QScopedPointer<CKeyboard> m_keyboardPtt; /*!< handler for PTT */
|
||||
bool m_pushToTalk; /*!< flag, PTT pressed */
|
||||
float m_inputSquelch;
|
||||
Cvatlib_Voice_Simple::agc m_micTestResult;
|
||||
|
||||
typedef QMap<ComUnit, QSet<QString>> TMapRoomCallsigns;
|
||||
TMapRoomCallsigns m_voiceRoomCallsigns;
|
||||
QSet<QString> m_voiceRoomCallsignsUpdate;
|
||||
|
||||
// Need to keep the roomIndex because GetRoomUserList does not specifiy it
|
||||
// KB: I would remove this approach, it is potentially unsafe
|
||||
// Maybe just use 2 "wrapper" callbacks, which then set explicitly the voice room (it is only 2 methods)
|
||||
int32_t m_queryUserRoomIndex;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // guard
|
||||
Reference in New Issue
Block a user