mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-20 20:40:29 +08:00
committed by
Mathew Sutcliffe
parent
b511f2ffaa
commit
7292e265fb
@@ -21,6 +21,9 @@
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* Interface to a connection to a ATC voice server for use in flight simulation.
|
||||||
|
*/
|
||||||
class IVoiceClient : public QObject
|
class IVoiceClient : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -54,17 +57,25 @@ namespace BlackCore
|
|||||||
virtual bool isConnected(const uint32_t comUnit) = 0;
|
virtual bool isConnected(const uint32_t comUnit) = 0;
|
||||||
|
|
||||||
|
|
||||||
// The following methods should be called everytime you receive a update signal.
|
// The following method should be called everytime you receive a user update signal
|
||||||
// Reason:
|
|
||||||
// We cannot say when the device and user lists are completed. Instead information is cached internally
|
|
||||||
// and signals emitted in case of a change. This way other objects can listen to this signals and call the getter
|
|
||||||
// again.
|
|
||||||
virtual void roomUserList(const uint32_t comUnit) = 0;
|
virtual void roomUserList(const uint32_t comUnit) = 0;
|
||||||
virtual const QList<BlackMisc::Voice::CInputAudioDevice> & audioInputDevices(const uint32_t comUnit) const = 0;
|
|
||||||
virtual const QList<BlackMisc::Voice::COutputAudioDevice> & audioOutputDevices(const uint32_t comUnit) const = 0;
|
|
||||||
|
|
||||||
virtual void setInputDevice(const uint32_t comUnit, BlackMisc::Voice::CInputAudioDevice &device) = 0;
|
// Hardware devices
|
||||||
virtual void setOutputDevice(const uint32_t comUnit, BlackMisc::Voice::COutputAudioDevice &device) = 0;
|
virtual const QList<BlackMisc::Voice::CInputAudioDevice> & audioInputDevices() const = 0;
|
||||||
|
virtual const QList<BlackMisc::Voice::COutputAudioDevice> & audioOutputDevices() const = 0;
|
||||||
|
|
||||||
|
virtual const BlackMisc::Voice::CInputAudioDevice & defaultAudioInputDevice() const = 0;
|
||||||
|
virtual const BlackMisc::Voice::COutputAudioDevice & defaultAudioOutputDevice() const = 0;
|
||||||
|
|
||||||
|
virtual void setInputDevice(const BlackMisc::Voice::CInputAudioDevice &device) = 0;
|
||||||
|
virtual void setOutputDevice(const BlackMisc::Voice::COutputAudioDevice &device) = 0;
|
||||||
|
|
||||||
|
// Mic tests
|
||||||
|
|
||||||
|
virtual void runSquelchTest() = 0;
|
||||||
|
virtual void runMicTest() = 0;
|
||||||
|
|
||||||
|
virtual float inputSquelch() const = 0;
|
||||||
|
|
||||||
virtual const BlackMisc::Voice::CVoiceRoom &voiceRoom (const uint32_t comUnit) = 0;
|
virtual const BlackMisc::Voice::CVoiceRoom &voiceRoom (const uint32_t comUnit) = 0;
|
||||||
|
|
||||||
@@ -86,6 +97,13 @@ namespace BlackCore
|
|||||||
void audioStarted(const uint32_t comUnit);
|
void audioStarted(const uint32_t comUnit);
|
||||||
void audioStopped(const uint32_t comUnit);
|
void audioStopped(const uint32_t comUnit);
|
||||||
|
|
||||||
|
// Test signals
|
||||||
|
void squelchTestFinished();
|
||||||
|
void micTestFinished();
|
||||||
|
|
||||||
|
// non protocol related signals
|
||||||
|
void exception(const QString &message, bool fatal = false); // let remote places know there was an exception
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,21 +6,33 @@
|
|||||||
#include "voiceclient_vatlib.h"
|
#include "voiceclient_vatlib.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
CVoiceClientVatlib::CVoiceClientVatlib(QObject *parent) :
|
CVoiceClientVatlib::CVoiceClientVatlib(QObject *parent) :
|
||||||
IVoiceClient(parent),
|
IVoiceClient(parent),
|
||||||
m_voice(Create_Cvatlib_Voice_Simple())
|
m_voice(Create_Cvatlib_Voice_Simple()),
|
||||||
|
m_inputSquelch(-1)
|
||||||
{
|
{
|
||||||
m_voice->Setup(true, 3290, 2, 1, onRoomStatusUpdate, this);
|
try
|
||||||
m_voice->GetInputDevices(onInputHardwareDeviceReceived, this);
|
{
|
||||||
m_voice->GetOutputDevices(onOutputHardwareDeviceReceived, this);
|
m_voice->Setup(true, 3290, 2, 1, onRoomStatusUpdate, this);
|
||||||
|
m_voice->GetInputDevices(onInputHardwareDeviceReceived, this);
|
||||||
|
m_voice->GetOutputDevices(onOutputHardwareDeviceReceived, this);
|
||||||
|
|
||||||
|
// TODO: read audio device settings here and init with the same devices
|
||||||
|
// If not settings are there or it is the first run, use the default one
|
||||||
|
setInputDevice(defaultAudioInputDevice());
|
||||||
|
setOutputDevice(defaultAudioOutputDevice());
|
||||||
|
|
||||||
|
startTimer(100);
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
}
|
}
|
||||||
|
|
||||||
CVoiceClientVatlib::~CVoiceClientVatlib()
|
CVoiceClientVatlib::~CVoiceClientVatlib()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::setCallsign(const BlackMisc::Aviation::CCallsign &callsign)
|
void CVoiceClientVatlib::setCallsign(const BlackMisc::Aviation::CCallsign &callsign)
|
||||||
@@ -38,54 +50,131 @@ namespace BlackCore
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::setVolume(const uint32_t comIndex, const uint32_t volumne)
|
void CVoiceClientVatlib::setVolume(const uint32_t comUnit, const uint32_t volumne)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::startTransmitting(const uint32_t comIndex)
|
void CVoiceClientVatlib::startTransmitting(const uint32_t comUnit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::stopTransmitting(const uint32_t comIndex)
|
void CVoiceClientVatlib::stopTransmitting(const uint32_t comUnit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVoiceClientVatlib::isReceiving(const uint32_t comIndex)
|
bool CVoiceClientVatlib::isReceiving(const uint32_t comUnit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CVoiceClientVatlib::isConnected(const uint32_t comIndex)
|
bool CVoiceClientVatlib::isConnected(const uint32_t comUnit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::roomUserList(const uint32_t comIndex)
|
void CVoiceClientVatlib::roomUserList(const uint32_t comUnit)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<BlackMisc::Voice::CInputAudioDevice> &CVoiceClientVatlib::audioInputDevices(const uint32_t comIndex) const
|
const QList<BlackMisc::Voice::CInputAudioDevice> &CVoiceClientVatlib::audioInputDevices() const
|
||||||
{
|
{
|
||||||
return m_inputDevices;
|
return m_inputDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QList<BlackMisc::Voice::COutputAudioDevice> &CVoiceClientVatlib::audioOutputDevices(const uint32_t comIndex) const
|
const QList<BlackMisc::Voice::COutputAudioDevice> &CVoiceClientVatlib::audioOutputDevices() const
|
||||||
{
|
{
|
||||||
return m_outputDevices;
|
return m_outputDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::setInputDevice(const uint32_t comUnit, BlackMisc::Voice::CInputAudioDevice &device)
|
const BlackMisc::Voice::CInputAudioDevice & CVoiceClientVatlib::defaultAudioInputDevice() const
|
||||||
{
|
{
|
||||||
|
foreach(BlackMisc::Voice::CInputAudioDevice inputDevice, m_inputDevices)
|
||||||
|
{
|
||||||
|
if(inputDevice.name().contains("[default]", Qt::CaseInsensitive))
|
||||||
|
return inputDevice;
|
||||||
|
}
|
||||||
|
return BlackMisc::Voice::CInputAudioDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVoiceClientVatlib::setOutputDevice(const uint32_t comUnit, BlackMisc::Voice::COutputAudioDevice &device)
|
const BlackMisc::Voice::COutputAudioDevice & CVoiceClientVatlib::defaultAudioOutputDevice() const
|
||||||
{
|
{
|
||||||
|
foreach(BlackMisc::Voice::COutputAudioDevice outputDevice, m_outputDevices)
|
||||||
|
{
|
||||||
|
if(outputDevice.name().contains("[default]", Qt::CaseInsensitive))
|
||||||
|
return outputDevice;
|
||||||
|
}
|
||||||
|
return BlackMisc::Voice::COutputAudioDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::setInputDevice(const BlackMisc::Voice::CInputAudioDevice &device)
|
||||||
|
{
|
||||||
|
if (!device.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if( !m_voice->SetInputDevice(device.index()))
|
||||||
|
{
|
||||||
|
qWarning() << "SetInputDevice() failed";
|
||||||
|
}
|
||||||
|
if (!m_voice->IsInputDeviceAlive())
|
||||||
|
{
|
||||||
|
qWarning() << "Input device hit a fatal error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::setOutputDevice(const BlackMisc::Voice::COutputAudioDevice &device)
|
||||||
|
{
|
||||||
|
if (!device.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_voice->SetOutputDevice(0, device.index());
|
||||||
|
|
||||||
|
if (!m_voice->IsOutputDeviceAlive(0))
|
||||||
|
{
|
||||||
|
qWarning() << "Input device hit a fatal error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (...) { exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::runSquelchTest()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Q_ASSERT_X (m_voice->IsValid() && m_voice->IsSetup(), "CVoiceClientVatlib", "Cvatlib_Voice_Simple invalid or not setup!");
|
||||||
|
m_voice->BeginFindSquelch();
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
|
||||||
|
// Start the timer only if no exception was thrown before
|
||||||
|
QTimer::singleShot(5000, this, SLOT(onEndFindSquelch()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::runMicTest()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Q_ASSERT_X (m_voice->IsValid() && m_voice->IsSetup(), "CVoiceClientVatlib", "Cvatlib_Voice_Simple invalid or not setup!");
|
||||||
|
m_voice->BeginMicTest();
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
|
||||||
|
// Start the timer only if no exception was thrown before
|
||||||
|
QTimer::singleShot(5000, this, SLOT(onEndMicTest()));
|
||||||
|
}
|
||||||
|
|
||||||
|
float CVoiceClientVatlib::inputSquelch() const
|
||||||
|
{
|
||||||
|
return m_inputSquelch;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BlackMisc::Voice::CVoiceRoom &CVoiceClientVatlib::voiceRoom(const uint32_t comUnit)
|
const BlackMisc::Voice::CVoiceRoom &CVoiceClientVatlib::voiceRoom(const uint32_t comUnit)
|
||||||
@@ -93,6 +182,45 @@ namespace BlackCore
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::timerEvent(QTimerEvent *)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Q_ASSERT_X (m_voice->IsValid() && m_voice->IsSetup(), "CVoiceClientVatlib", "Cvatlib_Voice_Simple invalid or not setup!");
|
||||||
|
m_voice->DoProcessing();
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::onEndFindSquelch()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Q_ASSERT_X (m_voice->IsValid() && m_voice->IsSetup(), "CVoiceClientVatlib", "Cvatlib_Voice_Simple invalid or not setup!");
|
||||||
|
|
||||||
|
m_voice->EndFindSquelch();
|
||||||
|
|
||||||
|
//TODO: store captured squelch
|
||||||
|
m_inputSquelch = m_voice->GetInputSquelch();
|
||||||
|
qDebug() << m_inputSquelch;
|
||||||
|
emit squelchTestFinished();
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::onEndMicTest()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Q_ASSERT_X (m_voice->IsValid() && m_voice->IsSetup(), "CVoiceClientVatlib", "Cvatlib_Voice_Simple invalid or not setup!");
|
||||||
|
|
||||||
|
Cvatlib_Voice_Simple::agc micTestResult = m_voice->EndMicTest();
|
||||||
|
qDebug() << micTestResult;
|
||||||
|
emit micTestFinished();
|
||||||
|
}
|
||||||
|
catch (...) { this->exceptionDispatcher(Q_FUNC_INFO); }
|
||||||
|
}
|
||||||
|
|
||||||
/********************************** * * * * * * * * * * * * * * * * * * * ************************************/
|
/********************************** * * * * * * * * * * * * * * * * * * * ************************************/
|
||||||
/********************************** shimlib callbacks ************************************/
|
/********************************** shimlib callbacks ************************************/
|
||||||
/********************************** * * * * * * * * * * * * * * * * * * * ************************************/
|
/********************************** * * * * * * * * * * * * * * * * * * * ************************************/
|
||||||
@@ -124,4 +252,39 @@ namespace BlackCore
|
|||||||
cbvar_cast(cbVar)->m_outputDevices.append(outputDevice);
|
cbvar_cast(cbVar)->m_outputDevices.append(outputDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CVoiceClientVatlib::exceptionDispatcher(const char *caller)
|
||||||
|
{
|
||||||
|
QString msg("Caller: ");
|
||||||
|
msg.append(caller).append(" ").append("Exception: ");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (const NetworkNotConnectedException &e)
|
||||||
|
{
|
||||||
|
// this could be caused by a race condition during normal operation, so not an error
|
||||||
|
msg.append("NetworkNotConnectedException").append(" ").append(e.what());
|
||||||
|
emit this->exception(msg);
|
||||||
|
qDebug() << "NetworkNotConnectedException caught in " << caller << "\n" << e.what();
|
||||||
|
}
|
||||||
|
catch (const VatlibException &e)
|
||||||
|
{
|
||||||
|
msg.append("VatlibException").append(" ").append(e.what());
|
||||||
|
emit this->exception(msg, true);
|
||||||
|
qFatal("VatlibException caught in %s\n%s", caller, e.what());
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
msg.append("std::exception").append(" ").append(e.what());
|
||||||
|
emit this->exception(msg, true);
|
||||||
|
qFatal("std::exception caught in %s\n%s", caller, e.what());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
msg.append("unknown exception");
|
||||||
|
emit this->exception(msg, true);
|
||||||
|
qFatal("Unknown exception caught in %s", caller);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace BlackCore
|
} // namespace BlackCore
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
|
|
||||||
namespace BlackCore
|
namespace BlackCore
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* Vatlib implementation of the IVoiceClient interface.
|
||||||
|
*/
|
||||||
class CVoiceClientVatlib : public IVoiceClient
|
class CVoiceClientVatlib : public IVoiceClient
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -32,11 +34,26 @@ namespace BlackCore
|
|||||||
virtual bool isConnected(const uint32_t comUnit);
|
virtual bool isConnected(const uint32_t comUnit);
|
||||||
|
|
||||||
virtual void roomUserList(const uint32_t comUnit);
|
virtual void roomUserList(const uint32_t comUnit);
|
||||||
virtual const QList<BlackMisc::Voice::CInputAudioDevice> &audioInputDevices(const uint32_t comUnit) const ;
|
|
||||||
virtual const QList<BlackMisc::Voice::COutputAudioDevice> & audioOutputDevices(const uint32_t comUnit) const;
|
|
||||||
|
|
||||||
virtual void setInputDevice(const uint32_t comUnit, BlackMisc::Voice::CInputAudioDevice &device);
|
// Hardware devices
|
||||||
virtual void setOutputDevice(const uint32_t comUnit, BlackMisc::Voice::COutputAudioDevice &device);
|
// 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 QList<BlackMisc::Voice::CInputAudioDevice> & audioInputDevices() const ;
|
||||||
|
virtual const QList<BlackMisc::Voice::COutputAudioDevice> & audioOutputDevices() const;
|
||||||
|
|
||||||
|
virtual const BlackMisc::Voice::CInputAudioDevice & defaultAudioInputDevice() const;
|
||||||
|
virtual const BlackMisc::Voice::COutputAudioDevice & defaultAudioOutputDevice() const;
|
||||||
|
|
||||||
|
virtual void setInputDevice(const BlackMisc::Voice::CInputAudioDevice &device);
|
||||||
|
virtual void setOutputDevice(const BlackMisc::Voice::COutputAudioDevice &device);
|
||||||
|
|
||||||
|
// Mic tests
|
||||||
|
virtual void runSquelchTest();
|
||||||
|
virtual void runMicTest();
|
||||||
|
|
||||||
|
virtual float inputSquelch() const;
|
||||||
|
|
||||||
|
|
||||||
virtual const BlackMisc::Voice::CVoiceRoom &voiceRoom (const uint32_t comUnit);
|
virtual const BlackMisc::Voice::CVoiceRoom &voiceRoom (const uint32_t comUnit);
|
||||||
|
|
||||||
@@ -44,6 +61,14 @@ namespace BlackCore
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
protected: // QObject overrides
|
||||||
|
virtual void timerEvent(QTimerEvent *);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
// slots for Mic tests
|
||||||
|
void onEndFindSquelch();
|
||||||
|
void onEndMicTest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// shimlib callbacks
|
// shimlib callbacks
|
||||||
@@ -52,11 +77,23 @@ namespace BlackCore
|
|||||||
static void onInputHardwareDeviceReceived(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);
|
static void onOutputHardwareDeviceReceived(Cvatlib_Voice_Simple* obj, const char* name, void* cbVar);
|
||||||
|
|
||||||
QScopedPointer<Cvatlib_Voice_Simple> m_voice;
|
void exceptionDispatcher(const char *caller);
|
||||||
|
|
||||||
|
struct Cvatlib_Voice_Simple_Deleter
|
||||||
|
{
|
||||||
|
static inline void cleanup(Cvatlib_Voice_Simple *pointer)
|
||||||
|
{
|
||||||
|
pointer->Destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QScopedPointer<Cvatlib_Voice_Simple, Cvatlib_Voice_Simple_Deleter> m_voice;
|
||||||
BlackMisc::Aviation::CCallsign m_callsign;
|
BlackMisc::Aviation::CCallsign m_callsign;
|
||||||
QMap<uint32_t, BlackMisc::Voice::CVoiceRoom> m_voiceRoomMap;
|
QMap<uint32_t, BlackMisc::Voice::CVoiceRoom> m_voiceRoomMap;
|
||||||
QList<BlackMisc::Voice::CInputAudioDevice> m_inputDevices;
|
QList<BlackMisc::Voice::CInputAudioDevice> m_inputDevices;
|
||||||
QList<BlackMisc::Voice::COutputAudioDevice> m_outputDevices;
|
QList<BlackMisc::Voice::COutputAudioDevice> m_outputDevices;
|
||||||
|
|
||||||
|
float m_inputSquelch;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace BlackCore
|
} // namespace BlackCore
|
||||||
|
|||||||
Reference in New Issue
Block a user