mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-14 00:25:35 +08:00
committed by
Mathew Sutcliffe
parent
b511f2ffaa
commit
7292e265fb
@@ -21,6 +21,9 @@
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
/*!
|
||||
* Interface to a connection to a ATC voice server for use in flight simulation.
|
||||
*/
|
||||
class IVoiceClient : public QObject
|
||||
{
|
||||
|
||||
@@ -54,17 +57,25 @@ namespace BlackCore
|
||||
virtual bool isConnected(const uint32_t comUnit) = 0;
|
||||
|
||||
|
||||
// The following methods should be called everytime you receive a 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.
|
||||
// The following method should be called everytime you receive a user update signal
|
||||
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;
|
||||
virtual void setOutputDevice(const uint32_t comUnit, BlackMisc::Voice::COutputAudioDevice &device) = 0;
|
||||
// Hardware devices
|
||||
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;
|
||||
|
||||
@@ -86,6 +97,13 @@ namespace BlackCore
|
||||
void audioStarted(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:
|
||||
|
||||
};
|
||||
|
||||
@@ -6,21 +6,33 @@
|
||||
#include "voiceclient_vatlib.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
CVoiceClientVatlib::CVoiceClientVatlib(QObject *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);
|
||||
m_voice->GetInputDevices(onInputHardwareDeviceReceived, this);
|
||||
m_voice->GetOutputDevices(onOutputHardwareDeviceReceived, this);
|
||||
try
|
||||
{
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const QList<BlackMisc::Voice::COutputAudioDevice> &CVoiceClientVatlib::audioOutputDevices(const uint32_t comIndex) const
|
||||
const QList<BlackMisc::Voice::COutputAudioDevice> &CVoiceClientVatlib::audioOutputDevices() const
|
||||
{
|
||||
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)
|
||||
@@ -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 ************************************/
|
||||
/********************************** * * * * * * * * * * * * * * * * * * * ************************************/
|
||||
@@ -124,4 +252,39 @@ namespace BlackCore
|
||||
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
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
namespace BlackCore
|
||||
{
|
||||
|
||||
/*!
|
||||
* Vatlib implementation of the IVoiceClient interface.
|
||||
*/
|
||||
class CVoiceClientVatlib : public IVoiceClient
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -32,11 +34,26 @@ namespace BlackCore
|
||||
virtual bool isConnected(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);
|
||||
virtual void setOutputDevice(const uint32_t comUnit, BlackMisc::Voice::COutputAudioDevice &device);
|
||||
// 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 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);
|
||||
|
||||
@@ -44,6 +61,14 @@ namespace BlackCore
|
||||
|
||||
public slots:
|
||||
|
||||
protected: // QObject overrides
|
||||
virtual void timerEvent(QTimerEvent *);
|
||||
|
||||
private slots:
|
||||
// slots for Mic tests
|
||||
void onEndFindSquelch();
|
||||
void onEndMicTest();
|
||||
|
||||
private:
|
||||
|
||||
// shimlib callbacks
|
||||
@@ -52,11 +77,23 @@ namespace BlackCore
|
||||
static void onInputHardwareDeviceReceived(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;
|
||||
QMap<uint32_t, BlackMisc::Voice::CVoiceRoom> m_voiceRoomMap;
|
||||
QList<BlackMisc::Voice::CInputAudioDevice> m_inputDevices;
|
||||
QList<BlackMisc::Voice::COutputAudioDevice> m_outputDevices;
|
||||
|
||||
float m_inputSquelch;
|
||||
};
|
||||
|
||||
} // namespace BlackCore
|
||||
|
||||
Reference in New Issue
Block a user