kopia lustrzana https://gitlab.com/eliggett/wfview
Various compatibility improvements
rodzic
d86f8958b2
commit
86502a5c3a
|
@ -125,6 +125,13 @@ bool audioHandler::init(audioSetup setupIn)
|
|||
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "No channels found, aborting setup.";
|
||||
return false;
|
||||
}
|
||||
if (format.channelCount() == 1 && setup.format.channelCount() == 2) {
|
||||
format.setChannelCount(2);
|
||||
if (!setup.port.isFormatSupported(format)) {
|
||||
qCritical(logAudio()) << (setup.isinput ? "Input" : "Output") << "Cannot request stereo input!";
|
||||
format.setChannelCount(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (format.sampleSize() == 24) {
|
||||
// We can't convert this easily
|
||||
|
@ -494,6 +501,13 @@ void audioHandler::getNextAudioChunk()
|
|||
samplesTemp = Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesF.data(), samplesF.size() / 2);
|
||||
samplesF = samplesTemp;
|
||||
}
|
||||
else if (format.channelCount() == 1 && setup.format.channelCount() == 2) {
|
||||
// Convert mono to stereo if required
|
||||
Eigen::VectorXf samplesTemp(samplesF.size() * 2);
|
||||
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data(), samplesF.size()) = samplesF;
|
||||
Eigen::Map<Eigen::VectorXf, 0, Eigen::InnerStride<2> >(samplesTemp.data() + 1, samplesF.size()) = samplesF;
|
||||
samplesF = samplesTemp;
|
||||
}
|
||||
|
||||
//qInfo(logAudio()) << "Sending audio len" << livePacket.data.length() << "remaining" << tempBuf.data.length() << "resampled" << samplesF.size();
|
||||
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -57,11 +57,11 @@ int main(int argc, char *argv[])
|
|||
keyboard* kb = new keyboard();
|
||||
kb->start();
|
||||
#else
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QApplication a(argc, argv);
|
||||
a.setOrganizationName("wfview");
|
||||
a.setOrganizationDomain("wfview.org");
|
||||
a.setApplicationName("wfview");
|
||||
a.setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
#endif
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
|
|
115
packettypes.h
115
packettypes.h
|
@ -121,6 +121,7 @@ typedef union audio_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
|
||||
quint16 ident; // 0x10
|
||||
quint16 sendseq; // 0x12
|
||||
quint16 unused; // 0x14
|
||||
|
@ -165,18 +166,24 @@ typedef union token_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[3]; // 0x10
|
||||
quint16 code; // 0x13
|
||||
quint16 res; // 0x15
|
||||
quint8 innerseq; // 0x17
|
||||
char unusedb; // 0x18
|
||||
char unusedc; // 0x19
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
char unusedd[7]; // 0x20
|
||||
quint16 commoncap; // 0x27
|
||||
char unuseddd; // 0x29
|
||||
char macaddress[6]; // 0x2a
|
||||
union {
|
||||
struct {
|
||||
quint16 authstartid; // 0x20
|
||||
char unusedg[5]; // 0x22
|
||||
quint16 commoncap; // 0x27
|
||||
char unusedh; // 0x29
|
||||
quint8 macaddress[6]; // 0x2a
|
||||
};
|
||||
quint8 guid[GUIDLEN]; // 0x20
|
||||
};
|
||||
quint32 response; // 0x30
|
||||
char unusede[12]; // 0x34
|
||||
};
|
||||
|
@ -192,19 +199,24 @@ typedef union status_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[3]; // 0x10
|
||||
quint16 code; // 0x13
|
||||
quint16 res; // 0x15
|
||||
quint8 innerseq; // 0x17
|
||||
char unusedb; // 0x18
|
||||
char unusedc; // 0x19
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
char unusedd[6]; // 0x20
|
||||
quint16 unknown; // 0x26
|
||||
char unusede; // 0x28
|
||||
char unusedf; // 0x29
|
||||
quint8 macaddress[6]; // 0x2a
|
||||
union {
|
||||
struct {
|
||||
quint16 authstartid; // 0x20
|
||||
char unusedd[5]; // 0x22
|
||||
quint16 commoncap; // 0x27
|
||||
char unusede; // 0x29
|
||||
quint8 macaddress[6]; // 0x2a
|
||||
};
|
||||
quint8 guid[GUIDLEN]; // 0x20
|
||||
};
|
||||
quint32 error; // 0x30
|
||||
char unusedg[12]; // 0x34
|
||||
char disc; // 0x40
|
||||
|
@ -226,12 +238,12 @@ typedef union login_response_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[3]; // 0x10
|
||||
quint16 code; // 0x13
|
||||
quint16 res; // 0x15
|
||||
quint8 innerseq; // 0x17
|
||||
char unusedb; // 0x18
|
||||
char unusedc; // 0x19
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
quint16 authstartid; // 0x20
|
||||
|
@ -253,12 +265,12 @@ typedef union login_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[3]; // 0x10
|
||||
quint16 code; // 0x13
|
||||
quint16 res; // 0x15
|
||||
quint8 innerseq; // 0x17
|
||||
char unusedaa; // 0x18;
|
||||
char unusedb; // 0x19
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
char unusedc[32]; // 0x20
|
||||
|
@ -279,12 +291,12 @@ typedef union conninfo_packet {
|
|||
quint16 seq; // 0x06
|
||||
quint32 sentid; // 0x08
|
||||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[3]; // 0x10
|
||||
quint16 code; // 0x13
|
||||
quint16 res; // 0x15
|
||||
quint8 innerseq; // 0x17
|
||||
char unusedaa; // 0x18
|
||||
char unusedb; // 0x19
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
union {
|
||||
|
@ -293,7 +305,7 @@ typedef union conninfo_packet {
|
|||
char unusedg[5]; // 0x22
|
||||
quint16 commoncap; // 0x27
|
||||
char unusedh; // 0x29
|
||||
char macaddress[6]; // 0x2a
|
||||
quint8 macaddress[6]; // 0x2a
|
||||
};
|
||||
quint8 guid[GUIDLEN]; // 0x20
|
||||
};
|
||||
|
@ -328,19 +340,18 @@ typedef union conninfo_packet {
|
|||
|
||||
|
||||
// 0x64 length radio capabilities part of cap packet.
|
||||
/*
|
||||
};*/
|
||||
|
||||
typedef union radio_cap_packet {
|
||||
struct
|
||||
{
|
||||
union {
|
||||
struct {
|
||||
char unusede[7]; // 0x0
|
||||
quint16 commoncap; // 0x0
|
||||
char unused; // 0x0
|
||||
char macaddress[6]; // 0x0
|
||||
quint8 unusede[7]; // 0x00
|
||||
quint16 commoncap; // 0x07
|
||||
quint8 unused; // 0x09
|
||||
quint8 macaddress[6]; // 0x0a
|
||||
};
|
||||
quint8 guid[GUIDLEN]; // 0x0
|
||||
quint8 guid[GUIDLEN]; // 0x0
|
||||
};
|
||||
char name[32]; // 0x10
|
||||
char audio[32]; // 0x30
|
||||
|
@ -373,14 +384,14 @@ typedef union capabilities_packet {
|
|||
quint32 rcvdid; // 0x0c
|
||||
char unuseda[2]; // 0x10
|
||||
quint16 payloadsize; // 0x12
|
||||
quint16 res; // 0x14
|
||||
quint8 requestreply; // 0x13
|
||||
quint8 requesttype; // 0x14
|
||||
quint16 innerseq; // 0x16
|
||||
char unusedb; // 0x18
|
||||
char unusedc; // 0x19
|
||||
char unusedb[2]; // 0x18
|
||||
quint16 tokrequest; // 0x1a
|
||||
quint32 token; // 0x1c
|
||||
char unusedd[33]; // 0x20
|
||||
char numradios; // 0x41
|
||||
char unusedd[32]; // 0x20
|
||||
quint16 numradios; // 0x40
|
||||
};
|
||||
char packet[CAPABILITIES_SIZE];
|
||||
} *capabilities_packet_t;
|
||||
|
|
|
@ -1493,6 +1493,9 @@ void rigCommander::parseLevels()
|
|||
{
|
||||
switch(payloadIn[1])
|
||||
{
|
||||
case '\x01':
|
||||
// noise or s-meter sequelch status
|
||||
break;
|
||||
case '\x02':
|
||||
// S-Meter
|
||||
emit haveMeter(meterS, level);
|
||||
|
@ -1503,6 +1506,9 @@ void rigCommander::parseLevels()
|
|||
emit haveMeter(meterCenter, level);
|
||||
state.set(SMETER, level, false);
|
||||
break;
|
||||
case '\x05':
|
||||
// Various squelch (tone etc.)
|
||||
break;
|
||||
case '\x11':
|
||||
// RF-Power meter
|
||||
emit haveMeter(meterPower, level);
|
||||
|
@ -4709,7 +4715,7 @@ void rigCommander::printHex(const QByteArray &pdata, bool printVert, bool printH
|
|||
|
||||
void rigCommander::dataFromServer(QByteArray data)
|
||||
{
|
||||
//qInfo(logRig()) << "emit dataForComm()";
|
||||
//qInfo(logRig()) << "***************** emit dataForComm()" << data;
|
||||
emit dataForComm(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ void servermain::openRig()
|
|||
{
|
||||
//qInfo(logSystem()) << "Got rig";
|
||||
QMetaObject::invokeMethod(radio->rig, [=]() {
|
||||
radio->rig->commSetup(radio->civAddr, radio->serialPort, radio->baudRate, QString("none"),prefs.tcpPort);
|
||||
radio->rig->commSetup(radio->civAddr, radio->serialPort, radio->baudRate, QString("none"),prefs.tcpPort,0);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ void servermain::setServerToPrefs()
|
|||
udp = Q_NULLPTR;
|
||||
}
|
||||
|
||||
udp = new udpServer(serverConfig, serverTxSetup, serverRxSetup);
|
||||
udp = new udpServer(serverConfig);
|
||||
|
||||
serverThread = new QThread(this);
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ void udpHandler::dataReceived()
|
|||
case (TOKEN_SIZE): // Response to Token request
|
||||
{
|
||||
token_packet_t in = (token_packet_t)r.constData();
|
||||
if (in->res == 0x05 && in->type != 0x01)
|
||||
if (in->requesttype == 0x05 && in->requestreply == 0x02 && in->type != 0x01)
|
||||
{
|
||||
if (in->response == 0x0000)
|
||||
{
|
||||
|
@ -374,8 +374,9 @@ void udpHandler::dataReceived()
|
|||
qInfo(logUdp()) << "Got Connection status for:" << in->name << "Busy:" << in->busy << "Computer" << in->computer << "IP" << ip.toString();
|
||||
|
||||
// First we need to find this radio in our capabilities packet, there aren't many so just step through
|
||||
for (unsigned char f = 0; f < radios.length(); f++)
|
||||
for (unsigned char f = 0; f < radios.size(); f++)
|
||||
{
|
||||
|
||||
if ((radios[f].commoncap == 0x8010 &&
|
||||
radios[f].macaddress[0] == in->macaddress[0] &&
|
||||
radios[f].macaddress[1] == in->macaddress[1] &&
|
||||
|
@ -386,11 +387,15 @@ void udpHandler::dataReceived()
|
|||
!memcmp(radios[f].guid,in->guid, GUIDLEN))
|
||||
{
|
||||
emit setRadioUsage(f, in->busy, QString(in->computer), ip.toString());
|
||||
qDebug(logUdp()) << "Set radio usage num:" << f << in->name << "Busy:" << in->busy << "Computer" << in->computer << "IP" << ip.toString();
|
||||
}
|
||||
}
|
||||
if (in->type != 0x01 && !streamOpened) {
|
||||
|
||||
if (in->busy && numRadios == 1)
|
||||
if (!streamOpened && radios.size()==1) {
|
||||
|
||||
qDebug(logUdp()) << "Single radio available, can I connect to it?";
|
||||
|
||||
if (in->busy)
|
||||
{
|
||||
if (in->ipaddress != 0x00 && strcmp(in->computer, compName.toLocal8Bit()))
|
||||
{
|
||||
|
@ -400,17 +405,19 @@ void udpHandler::dataReceived()
|
|||
else {
|
||||
}
|
||||
}
|
||||
else if (!in->busy && numRadios == 1)
|
||||
else if (!in->busy)
|
||||
{
|
||||
qDebug(logUdp()) << "Attempting to connect to radio";
|
||||
status.message = devName + " available";
|
||||
|
||||
setCurrentRadio(0);
|
||||
}
|
||||
}
|
||||
else if (streamOpened)
|
||||
/* If another client connects/disconnects from the server, the server will emit
|
||||
/* If another client connects/disconnects from the server, the server will emit
|
||||
a CONNINFO packet, send our details to confirm we still want the stream */
|
||||
{
|
||||
//qDebug(logUdp()) << "I am already connected????";
|
||||
// Received while stream is open.
|
||||
//sendRequestStream();
|
||||
}
|
||||
|
@ -440,9 +447,16 @@ void udpHandler::dataReceived()
|
|||
qInfo(logUdp()) << this->metaObject()->className() << "Received radio capabilities, Name:" <<
|
||||
radio.name << " Audio:" <<
|
||||
radio.audio << "CIV:" << hex << (unsigned char)radio.civ <<
|
||||
"MAC:" << radio.macaddress[0] <<
|
||||
":" << radio.macaddress[1] <<
|
||||
":" << radio.macaddress[2] <<
|
||||
":" << radio.macaddress[3] <<
|
||||
":" << radio.macaddress[4] <<
|
||||
":" << radio.macaddress[5] <<
|
||||
"CAPF" << radio.capf;
|
||||
}
|
||||
emit requestRadioSelection(radios);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -505,8 +519,10 @@ void udpHandler::sendRequestStream()
|
|||
p.len = sizeof(p);
|
||||
p.sentid = myId;
|
||||
p.rcvdid = remoteId;
|
||||
p.code = 0x0180;
|
||||
p.res = 0x03;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requesttype = 0x03;
|
||||
p.requestreply = 0x01;
|
||||
|
||||
if (!useGuid) {
|
||||
p.commoncap = 0x8010;
|
||||
memcpy(&p.macaddress, macaddress, 6);
|
||||
|
@ -514,7 +530,7 @@ void udpHandler::sendRequestStream()
|
|||
else {
|
||||
memcpy(&p.guid, guid, GUIDLEN);
|
||||
}
|
||||
p.innerseq = authSeq++;
|
||||
p.innerseq = qToBigEndian(authSeq++);
|
||||
p.tokrequest = tokRequest;
|
||||
p.token = token;
|
||||
memcpy(&p.name, devName.toLocal8Bit().constData(), devName.length());
|
||||
|
@ -565,8 +581,11 @@ void udpHandler::sendLogin() // Only used on control stream.
|
|||
p.len = sizeof(p);
|
||||
p.sentid = myId;
|
||||
p.rcvdid = remoteId;
|
||||
p.code = 0x0170; // Not sure what this is?
|
||||
p.innerseq = authSeq++;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requesttype = 0x00;
|
||||
p.requestreply = 0x01;
|
||||
|
||||
p.innerseq = qToBigEndian(authSeq++);
|
||||
p.tokrequest = tokRequest;
|
||||
memcpy(p.username, usernameEncoded.constData(), usernameEncoded.length());
|
||||
memcpy(p.password, passwordEncoded.constData(), passwordEncoded.length());
|
||||
|
@ -585,9 +604,10 @@ void udpHandler::sendToken(uint8_t magic)
|
|||
p.len = sizeof(p);
|
||||
p.sentid = myId;
|
||||
p.rcvdid = remoteId;
|
||||
p.code = 0x0130; // Not sure what this is?
|
||||
p.res = magic;
|
||||
p.innerseq = authSeq++;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requesttype = magic;
|
||||
p.requestreply = 0x01;
|
||||
p.innerseq = qToBigEndian(authSeq++);
|
||||
p.tokrequest = tokRequest;
|
||||
p.token = token;
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
QUdpSocket* udp=Q_NULLPTR;
|
||||
uint32_t myId = 0;
|
||||
uint32_t remoteId = 0;
|
||||
uint8_t authSeq = 0x00;
|
||||
uint16_t authSeq = 0x30;
|
||||
uint16_t sendSeqB = 0;
|
||||
uint16_t sendSeq = 1;
|
||||
uint16_t lastReceivedSeq = 1;
|
||||
|
|
168
udpserver.cpp
168
udpserver.cpp
|
@ -4,10 +4,8 @@
|
|||
#define STALE_CONNECTION 15
|
||||
#define LOCK_PERIOD 10 // time to attempt to lock Mutex in ms
|
||||
#define AUDIO_SEND_PERIOD 20 //
|
||||
udpServer::udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAudio) :
|
||||
config(config),
|
||||
outAudio(outAudio),
|
||||
inAudio(inAudio)
|
||||
udpServer::udpServer(SERVERCONFIG* config) :
|
||||
config(config)
|
||||
{
|
||||
qInfo(logUdpServer()) << "Starting udp server";
|
||||
}
|
||||
|
@ -15,7 +13,7 @@ udpServer::udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAud
|
|||
void udpServer::init()
|
||||
{
|
||||
|
||||
for (RIGCONFIG* rig : config.rigs)
|
||||
for (RIGCONFIG* rig : config->rigs)
|
||||
{
|
||||
qDebug(logUdpServer()) << "CIV:" << rig->civAddr;
|
||||
qDebug(logUdpServer()) << "Model:" << rig->modelName;
|
||||
|
@ -53,36 +51,40 @@ void udpServer::init()
|
|||
}
|
||||
}
|
||||
|
||||
QString macTemp;
|
||||
foreach(QNetworkInterface netInterface, QNetworkInterface::allInterfaces())
|
||||
{
|
||||
// Return only the first non-loopback MAC Address
|
||||
if (!(netInterface.flags() & QNetworkInterface::IsLoopBack)) {
|
||||
macAddress = netInterface.hardwareAddress();
|
||||
macTemp = netInterface.hardwareAddress();
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&macAddress, macTemp.toLocal8Bit(), 6);
|
||||
memcpy(&macAddress, QByteArrayLiteral("\x00\x90\xc7").constData(), 3);
|
||||
|
||||
uint32_t addr = localIP.toIPv4Address();
|
||||
|
||||
qInfo(logUdpServer()) << "My IP Address:" << QHostAddress(addr).toString() << "My MAC Address:" << macAddress;
|
||||
qInfo(logUdpServer()) << "My IP Address:" << QHostAddress(addr).toString();
|
||||
|
||||
|
||||
controlId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.controlPort & 0xffff);
|
||||
civId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.civPort & 0xffff);
|
||||
audioId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config.audioPort & 0xffff);
|
||||
controlId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->controlPort & 0xffff);
|
||||
civId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->civPort & 0xffff);
|
||||
audioId = (addr >> 8 & 0xff) << 24 | (addr & 0xff) << 16 | (config->audioPort & 0xffff);
|
||||
|
||||
qInfo(logUdpServer()) << "Server Binding Control to: " << config.controlPort;
|
||||
qInfo(logUdpServer()) << "Server Binding Control to: " << config->controlPort;
|
||||
udpControl = new QUdpSocket(this);
|
||||
udpControl->bind(config.controlPort);
|
||||
udpControl->bind(config->controlPort);
|
||||
QUdpSocket::connect(udpControl, &QUdpSocket::readyRead, this, &udpServer::controlReceived);
|
||||
|
||||
qInfo(logUdpServer()) << "Server Binding CIV to: " << config.civPort;
|
||||
qInfo(logUdpServer()) << "Server Binding CIV to: " << config->civPort;
|
||||
udpCiv = new QUdpSocket(this);
|
||||
udpCiv->bind(config.civPort);
|
||||
udpCiv->bind(config->civPort);
|
||||
QUdpSocket::connect(udpCiv, &QUdpSocket::readyRead, this, &udpServer::civReceived);
|
||||
|
||||
qInfo(logUdpServer()) << "Server Binding Audio to: " << config.audioPort;
|
||||
qInfo(logUdpServer()) << "Server Binding Audio to: " << config->audioPort;
|
||||
udpAudio = new QUdpSocket(this);
|
||||
udpAudio->bind(config.audioPort);
|
||||
udpAudio->bind(config->audioPort);
|
||||
QUdpSocket::connect(udpAudio, &QUdpSocket::readyRead, this, &udpServer::audioReceived);
|
||||
|
||||
wdTimer = new QTimer();
|
||||
|
@ -129,8 +131,8 @@ udpServer::~udpServer()
|
|||
|
||||
void udpServer::receiveRigCaps(rigCapabilities caps)
|
||||
{
|
||||
for (RIGCONFIG* rig: config.rigs) {
|
||||
if (!memcmp(rig->guid, caps.guid, GUIDLEN)) {
|
||||
for (RIGCONFIG* rig: config->rigs) {
|
||||
if (!memcmp(rig->guid, caps.guid, GUIDLEN) || config->rigs.size()==1) {
|
||||
// Matching rig, fill-in missing details
|
||||
rig->rigAvailable = true;
|
||||
rig->modelName = caps.modelName;
|
||||
|
@ -173,8 +175,8 @@ void udpServer::controlReceived()
|
|||
current->timeConnected = QDateTime::currentDateTime();
|
||||
current->ipAddress = datagram.senderAddress();
|
||||
current->port = datagram.senderPort();
|
||||
current->civPort = config.civPort;
|
||||
current->audioPort = config.audioPort;
|
||||
current->civPort = config->civPort;
|
||||
current->audioPort = config->audioPort;
|
||||
current->myId = controlId;
|
||||
current->remoteId = qFromLittleEndian<quint32>(r.mid(8, 4));
|
||||
current->socket = udpControl;
|
||||
|
@ -194,8 +196,16 @@ void udpServer::controlReceived()
|
|||
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": New Control connection created";
|
||||
|
||||
|
||||
if (connMutex.try_lock_for(std::chrono::milliseconds(LOCK_PERIOD)))
|
||||
{
|
||||
// Quick hack to replace the GUID with a MAC address.
|
||||
if (config->rigs.size() == 1) {
|
||||
memset(config->rigs.first()->guid, 0, GUIDLEN);
|
||||
config->rigs.first()->commoncap = (quint16)0x8010;
|
||||
memcpy(config->rigs.first()->macaddress, macAddress, 6);
|
||||
memcpy(current->guid, config->rigs.first()->guid, GUIDLEN);
|
||||
}
|
||||
controlClients.append(current);
|
||||
connMutex.unlock();
|
||||
}
|
||||
|
@ -255,26 +265,26 @@ void udpServer::controlReceived()
|
|||
token_packet_t in = (token_packet_t)r.constData();
|
||||
current->rxSeq = in->seq;
|
||||
current->authInnerSeq = in->innerseq;
|
||||
memcpy(current->macaddress, in->macaddress, 6);
|
||||
if (in->res == 0x02) {
|
||||
memcpy(current->guid, in->guid, GUIDLEN);
|
||||
if (in->requesttype == 0x02 && in->requestreply == 0x01) {
|
||||
// Request for new token
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received create token request";
|
||||
sendCapabilities(current);
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
sendConnectionInfo(current, radio->guid);
|
||||
}
|
||||
}
|
||||
else if (in->res == 0x01) {
|
||||
else if (in->requesttype == 0x01 && in->requestreply == 0x01) {
|
||||
// Token disconnect
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token disconnect request";
|
||||
sendTokenResponse(current, in->res);
|
||||
sendTokenResponse(current, in->requesttype);
|
||||
}
|
||||
else if (in->res == 0x04) {
|
||||
else if (in->requesttype == 0x04 && in->requestreply == 0x01) {
|
||||
// Disconnect audio/civ
|
||||
sendTokenResponse(current, in->res);
|
||||
sendTokenResponse(current, in->requesttype);
|
||||
current->isStreaming = false;
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
if (!memcmp(radio->guid, current->guid, GUIDLEN))
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
if (!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size() == 1)
|
||||
{
|
||||
sendConnectionInfo(current, radio->guid);
|
||||
}
|
||||
|
@ -282,7 +292,7 @@ void udpServer::controlReceived()
|
|||
}
|
||||
else {
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received token request";
|
||||
sendTokenResponse(current, in->res);
|
||||
sendTokenResponse(current, in->requesttype);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -290,7 +300,7 @@ void udpServer::controlReceived()
|
|||
{
|
||||
login_packet_t in = (login_packet_t)r.constData();
|
||||
qInfo(logUdpServer()) << current->ipAddress.toString() << ": Received 'login'";
|
||||
foreach(SERVERUSER user, config.users)
|
||||
foreach(SERVERUSER user, config->users)
|
||||
{
|
||||
QByteArray usercomp;
|
||||
passcode(user.username, usercomp);
|
||||
|
@ -345,9 +355,9 @@ void udpServer::controlReceived()
|
|||
|
||||
|
||||
audioSetup setup;
|
||||
setup.resampleQuality = config.resampleQuality;
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->txaudio == Q_NULLPTR)
|
||||
setup.resampleQuality = config->resampleQuality;
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
if ((!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size()==1) && radio->txaudio == Q_NULLPTR )
|
||||
{
|
||||
radio->txAudioSetup.codec = current->txCodec;
|
||||
radio->txAudioSetup.format.setSampleRate(current->txSampleRate);
|
||||
|
@ -380,7 +390,7 @@ void udpServer::controlReceived()
|
|||
connect(this, SIGNAL(haveAudioData(audioPacket)), radio->txaudio, SLOT(incomingAudio(audioPacket)));
|
||||
|
||||
}
|
||||
if (!memcmp(radio->guid, current->guid, GUIDLEN) && radio->rxaudio == Q_NULLPTR)
|
||||
if ((!memcmp(radio->guid, current->guid, GUIDLEN) || config->rigs.size() == 1) && radio->rxaudio == Q_NULLPTR)
|
||||
{
|
||||
#if !defined(PORTAUDIO) && !defined(RTAUDIO)
|
||||
qInfo(logUdpServer()) << "Radio" << radio->rigName << "audio input(RX) :" << radio->rxAudioSetup.port.deviceName();
|
||||
|
@ -404,7 +414,6 @@ void udpServer::controlReceived()
|
|||
|
||||
radio->rxAudioThread->start(QThread::TimeCriticalPriority);
|
||||
|
||||
connect(this, SIGNAL(setupRxAudio(audioSetup)), radio->rxaudio, SLOT(init(audioSetup)));
|
||||
connect(radio->rxAudioThread, SIGNAL(finished()), radio->rxaudio, SLOT(deleteLater()));
|
||||
connect(radio->rxaudio, SIGNAL(haveAudioData(audioPacket)), this, SLOT(receiveAudioData(audioPacket)));
|
||||
|
||||
|
@ -414,6 +423,7 @@ void udpServer::controlReceived()
|
|||
}, Qt::QueuedConnection);
|
||||
#else
|
||||
#warning "QT 5.9 is not fully supported multiple rigs will NOT work!"
|
||||
connect(this, SIGNAL(setupRxAudio(audioSetup)), radio->rxaudio, SLOT(init(audioSetup)));
|
||||
setupRxAudio(radio->rxAudioSetup);
|
||||
#endif
|
||||
|
||||
|
@ -573,10 +583,11 @@ void udpServer::civReceived()
|
|||
qDebug(logUdpServer()) << current->ipAddress.toString() << ": Detected invalid remote CI-V:" << hex << (quint8)r[lastFE+2];
|
||||
}
|
||||
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
if (!memcmp(radio->guid, current->guid, sizeof(radio->guid)))
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
if (!memcmp(radio->guid, current->guid, sizeof(radio->guid)) || config->rigs.size()==1)
|
||||
{
|
||||
// Only send to the rig that it belongs to!
|
||||
//qDebug(logUdpServer()) << "Sending data" << r.mid(0x15);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5,10,0))
|
||||
QMetaObject::invokeMethod(radio->rig, [=]() {
|
||||
radio->rig->dataFromServer(r.mid(0x15));;
|
||||
|
@ -1095,7 +1106,9 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
|
|||
p.innerseq = c->authInnerSeq;
|
||||
p.tokrequest = c->tokenRx;
|
||||
p.token = c->tokenTx;
|
||||
p.code = 0x0250;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requesttype = 0x00;
|
||||
p.requestreply = 0x01;
|
||||
|
||||
|
||||
if (!allowed) {
|
||||
|
@ -1108,7 +1121,8 @@ void udpServer::sendLoginResponse(CLIENT* c, bool allowed)
|
|||
c->retransmitTimer->stop();
|
||||
}
|
||||
else {
|
||||
strcpy(p.connection, "WFVIEW");
|
||||
//strcpy(p.connection, "WFVIEW");
|
||||
strcpy(p.connection, "FTTH");
|
||||
}
|
||||
|
||||
SEQBUFENTRY s;
|
||||
|
@ -1157,20 +1171,21 @@ void udpServer::sendCapabilities(CLIENT* c)
|
|||
p.innerseq = c->authInnerSeq;
|
||||
p.tokrequest = c->tokenRx;
|
||||
p.token = c->tokenTx;
|
||||
p.res = 0x0202;
|
||||
p.numradios = config.rigs.count();
|
||||
|
||||
p.requesttype = 0x02;
|
||||
p.requestreply = 0x02;
|
||||
p.numradios = qToBigEndian((quint16)config->rigs.size());
|
||||
SEQBUFENTRY s;
|
||||
s.seqNum = p.seq;
|
||||
s.timeSent = QTime::currentTime();
|
||||
s.retransmitCount = 0;
|
||||
|
||||
for (RIGCONFIG* rig : config.rigs) {
|
||||
for (RIGCONFIG* rig : config->rigs) {
|
||||
qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending Capabilities :" << c->txSeq << "for" << rig->modelName;
|
||||
radio_cap_packet r;
|
||||
memset(r.packet, 0x0, sizeof(r)); // We can't be sure it is initialized with 0x00!
|
||||
|
||||
memcpy(r.guid, rig->guid, GUIDLEN);
|
||||
|
||||
memcpy(r.name, rig->rigName.toLocal8Bit(), sizeof(r.name));
|
||||
memcpy(r.audio, QByteArrayLiteral("ICOM_VAUDIO").constData(), 11);
|
||||
|
||||
|
@ -1233,7 +1248,7 @@ void udpServer::sendCapabilities(CLIENT* c)
|
|||
}
|
||||
|
||||
p.len = sizeof(p)+s.data.length();
|
||||
p.payloadsize = sizeof(p)+s.data.length() - 0x0f;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) + s.data.length() - 0x10));
|
||||
|
||||
s.data.insert(0,QByteArray::fromRawData((const char*)p.packet, sizeof(p)));
|
||||
|
||||
|
@ -1271,8 +1286,8 @@ void udpServer::sendCapabilities(CLIENT* c)
|
|||
// Also used to display currently connected used information.
|
||||
void udpServer::sendConnectionInfo(CLIENT* c, quint8 guid[GUIDLEN])
|
||||
{
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
if (!memcmp(guid, radio->guid, GUIDLEN))
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
if (!memcmp(guid, radio->guid, GUIDLEN) || config->rigs.size()==1)
|
||||
{
|
||||
qInfo(logUdpServer()) << c->ipAddress.toString() << "(" << c->type << "): Sending ConnectionInfo :" << c->txSeq;
|
||||
conninfo_packet p;
|
||||
|
@ -1285,7 +1300,10 @@ void udpServer::sendConnectionInfo(CLIENT* c, quint8 guid[GUIDLEN])
|
|||
//p.innerseq = c->authInnerSeq; // Innerseq not used in user packet
|
||||
p.tokrequest = c->tokenRx;
|
||||
p.token = c->tokenTx;
|
||||
p.code = 0x0380;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requesttype = 0x00;
|
||||
p.requestreply = 0x03;
|
||||
|
||||
memcpy(p.guid, radio->guid, GUIDLEN);
|
||||
memcpy(p.name, radio->rigName.toLocal8Bit(), sizeof(p.name));
|
||||
|
||||
|
@ -1362,11 +1380,11 @@ void udpServer::sendTokenResponse(CLIENT* c, quint8 type)
|
|||
p.innerseq = c->authInnerSeq;
|
||||
p.tokrequest = c->tokenRx;
|
||||
p.token = c->tokenTx;
|
||||
p.code = 0x0230;
|
||||
memcpy(p.macaddress, c->macaddress, 6);
|
||||
p.commoncap = c->commonCap;
|
||||
p.res = type;
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
|
||||
memcpy(p.guid, c->guid, GUIDLEN);
|
||||
p.requesttype = type;
|
||||
p.requestreply = 0x02;
|
||||
|
||||
SEQBUFENTRY s;
|
||||
s.seqNum = p.seq;
|
||||
|
@ -1473,11 +1491,10 @@ void udpServer::sendStatus(CLIENT* c)
|
|||
p.innerseq = c->authInnerSeq;
|
||||
p.tokrequest = c->tokenRx;
|
||||
p.token = c->tokenTx;
|
||||
p.code = 0x0240;
|
||||
p.res = 0x03;
|
||||
p.unknown = 0x1000;
|
||||
p.unusede = (char)0x80;
|
||||
memcpy(p.macaddress, c->macaddress, 6);
|
||||
p.payloadsize = qToBigEndian((quint16)(sizeof(p) - 0x10));
|
||||
p.requestreply = 0x02;
|
||||
p.requesttype = 0x03;
|
||||
memcpy(p.guid, c->guid, GUIDLEN); // May be MAC address OR guid.
|
||||
|
||||
|
||||
p.civport = qToBigEndian(c->civPort);
|
||||
|
@ -1534,7 +1551,7 @@ void udpServer::dataForServer(QByteArray d)
|
|||
continue;
|
||||
}
|
||||
// Use the GUID to determine which radio the response is from
|
||||
if (memcmp(sender->getGUID(), client->guid, GUIDLEN))
|
||||
if (memcmp(sender->getGUID(), client->guid, GUIDLEN) && config->rigs.size()>1)
|
||||
{
|
||||
continue; // Rig guid doesn't match the one requested by the client.
|
||||
}
|
||||
|
@ -1571,7 +1588,7 @@ void udpServer::dataForServer(QByteArray d)
|
|||
}
|
||||
client->txSeqBuf.insert(p.seq, s);
|
||||
client->txSeq++;
|
||||
client->innerSeq++;
|
||||
//client->innerSeq = (qToBigEndian(qFromBigEndian(client->innerSeq) + 1));
|
||||
client->txMutex.unlock();
|
||||
}
|
||||
else {
|
||||
|
@ -1607,7 +1624,7 @@ void udpServer::receiveAudioData(const audioPacket& d)
|
|||
else {
|
||||
memcpy(guid, d.guid, GUIDLEN);
|
||||
}
|
||||
//qInfo(logUdpServer()) << "Server got:" << d.data.length();
|
||||
//qInfo(logUdpServer()) << "Server got:" << d.data.length();
|
||||
foreach(CLIENT * client, audioClients)
|
||||
{
|
||||
int len = 0;
|
||||
|
@ -1615,7 +1632,7 @@ void udpServer::receiveAudioData(const audioPacket& d)
|
|||
QByteArray partial;
|
||||
partial = d.data.mid(len, 1364);
|
||||
len = len + partial.length();
|
||||
if (client != Q_NULLPTR && client->connected && !memcmp(client->guid, guid, GUIDLEN)) {
|
||||
if (client != Q_NULLPTR && client->connected && (!memcmp(client->guid, guid, GUIDLEN) || config->rigs.size()== 1)) {
|
||||
audio_packet p;
|
||||
memset(p.packet, 0x0, sizeof(p)); // We can't be sure it is initialized with 0x00!
|
||||
p.len = sizeof(p) + partial.length();
|
||||
|
@ -1698,19 +1715,22 @@ void udpServer::sendRetransmitRequest(CLIENT* c)
|
|||
{
|
||||
for (auto it = c->rxMissing.begin(); it != c->rxMissing.end(); ++it)
|
||||
{
|
||||
if (&it.key() != Q_NULLPTR && it.value() < 4)
|
||||
if (&it.key() != Q_NULLPTR)
|
||||
{
|
||||
missingSeqs.append(it.key() & 0xff);
|
||||
missingSeqs.append(it.key() >> 8 & 0xff);
|
||||
missingSeqs.append(it.key() & 0xff);
|
||||
missingSeqs.append(it.key() >> 8 & 0xff);
|
||||
it.value()++;
|
||||
}
|
||||
if (it.value() < 4)
|
||||
{
|
||||
missingSeqs.append(it.key() & 0xff);
|
||||
missingSeqs.append(it.key() >> 8 & 0xff);
|
||||
missingSeqs.append(it.key() & 0xff);
|
||||
missingSeqs.append(it.key() >> 8 & 0xff);
|
||||
it.value()++;
|
||||
}
|
||||
|
||||
else {
|
||||
// We have tried 4 times to request this packet, time to give up!
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": No response for missing packet" << it.key() << "deleting";
|
||||
it = c->rxMissing.erase(it);
|
||||
else {
|
||||
// We have tried 4 times to request this packet, time to give up!
|
||||
qDebug(logUdp()) << this->metaObject()->className() << ": No response for missing packet" << it.key() << "deleting";
|
||||
it = c->rxMissing.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1844,8 +1864,8 @@ void udpServer::deleteConnection(QList<CLIENT*>* l, CLIENT* c)
|
|||
}
|
||||
|
||||
if (len == 0) {
|
||||
for (RIGCONFIG* radio : config.rigs) {
|
||||
if (!memcmp(radio->guid, guid, GUIDLEN))
|
||||
for (RIGCONFIG* radio : config->rigs) {
|
||||
if (!memcmp(radio->guid, guid, GUIDLEN) || config->rigs.size() == 1)
|
||||
{
|
||||
|
||||
if (radio->rxAudioThread != Q_NULLPTR) {
|
||||
|
|
23
udpserver.h
23
udpserver.h
|
@ -42,6 +42,7 @@ struct SERVERUSER {
|
|||
quint8 userType;
|
||||
};
|
||||
|
||||
|
||||
struct RIGCONFIG {
|
||||
QString serialPort;
|
||||
quint32 baudRate;
|
||||
|
@ -54,7 +55,17 @@ struct RIGCONFIG {
|
|||
audioSetup txAudioSetup;
|
||||
QString modelName;
|
||||
QString rigName;
|
||||
quint8 guid[GUIDLEN];
|
||||
#pragma pack(push, 1)
|
||||
union {
|
||||
struct {
|
||||
quint8 unused[7]; // 0x22
|
||||
quint16 commoncap; // 0x27
|
||||
quint8 unusedb; // 0x29
|
||||
quint8 macaddress[6]; // 0x2a
|
||||
};
|
||||
quint8 guid[GUIDLEN]; // 0x20
|
||||
};
|
||||
#pragma pack(pop)
|
||||
bool rigAvailable=false;
|
||||
rigCapabilities rigCaps;
|
||||
rigCommander* rig = Q_NULLPTR;
|
||||
|
@ -88,7 +99,7 @@ class udpServer : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
udpServer(SERVERCONFIG& config, audioSetup outAudio, audioSetup inAudio);
|
||||
udpServer(SERVERCONFIG* config);
|
||||
~udpServer();
|
||||
|
||||
public slots:
|
||||
|
@ -128,11 +139,11 @@ private:
|
|||
quint16 connSeq;
|
||||
quint16 pingSeq;
|
||||
quint32 rxPingTime; // 32bit as has other info
|
||||
quint8 authInnerSeq;
|
||||
quint16 authInnerSeq;
|
||||
quint16 authSeq;
|
||||
quint16 innerSeq;
|
||||
quint16 sendAudioSeq;
|
||||
quint8 macaddress[4];
|
||||
quint8 macaddress[6];
|
||||
quint16 tokenRx;
|
||||
quint32 tokenTx;
|
||||
quint32 commonCap;
|
||||
|
@ -186,13 +197,13 @@ private:
|
|||
void watchdog();
|
||||
void deleteConnection(QList<CLIENT*> *l, CLIENT* c);
|
||||
|
||||
SERVERCONFIG config;
|
||||
SERVERCONFIG *config;
|
||||
|
||||
QUdpSocket* udpControl = Q_NULLPTR;
|
||||
QUdpSocket* udpCiv = Q_NULLPTR;
|
||||
QUdpSocket* udpAudio = Q_NULLPTR;
|
||||
QHostAddress localIP;
|
||||
QString macAddress;
|
||||
quint8 macAddress[6];
|
||||
|
||||
quint32 controlId = 0;
|
||||
quint32 civId = 0;
|
||||
|
|
203
wfmain.cpp
203
wfmain.cpp
|
@ -111,10 +111,6 @@ wfmain::~wfmain()
|
|||
delete ui;
|
||||
delete settings;
|
||||
|
||||
#if defined(PORTAUDIO)
|
||||
Pa_Terminate();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void wfmain::closeEvent(QCloseEvent *event)
|
||||
|
@ -999,9 +995,9 @@ void wfmain::setServerToPrefs()
|
|||
|
||||
if (serverConfig.enabled) {
|
||||
serverConfig.lan = prefs.enableLAN;
|
||||
qInfo(logAudio()) << "Audio Input device " << serverRxSetup.name;
|
||||
qInfo(logAudio()) << "Audio Output device " << serverTxSetup.name;
|
||||
udp = new udpServer(serverConfig, serverTxSetup, serverRxSetup);
|
||||
qInfo(logAudio()) << "Audio Input device " << serverConfig.rigs.first()->rxAudioSetup.name;
|
||||
qInfo(logAudio()) << "Audio Output device " << serverConfig.rigs.first()->txAudioSetup.name;
|
||||
udp = new udpServer(&serverConfig);
|
||||
|
||||
serverThread = new QThread(this);
|
||||
|
||||
|
@ -1067,100 +1063,8 @@ void wfmain::setUIToPrefs()
|
|||
void wfmain::setAudioDevicesUI()
|
||||
{
|
||||
|
||||
#if defined(RTAUDIO)
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
RtAudio* audio = new RtAudio(RtAudio::Api::LINUX_ALSA);
|
||||
#elif defined(Q_OS_WIN)
|
||||
RtAudio* audio = new RtAudio(RtAudio::Api::WINDOWS_WASAPI);
|
||||
#elif defined(Q_OS_MACX)
|
||||
RtAudio* audio = new RtAudio(RtAudio::Api::MACOSX_CORE);
|
||||
#endif
|
||||
|
||||
|
||||
// Enumerate audio devices, need to do before settings are loaded.
|
||||
std::map<int, std::string> apiMap;
|
||||
apiMap[RtAudio::MACOSX_CORE] = "OS-X Core Audio";
|
||||
apiMap[RtAudio::WINDOWS_ASIO] = "Windows ASIO";
|
||||
apiMap[RtAudio::WINDOWS_DS] = "Windows DirectSound";
|
||||
apiMap[RtAudio::WINDOWS_WASAPI] = "Windows WASAPI";
|
||||
apiMap[RtAudio::UNIX_JACK] = "Jack Client";
|
||||
apiMap[RtAudio::LINUX_ALSA] = "Linux ALSA";
|
||||
apiMap[RtAudio::LINUX_PULSE] = "Linux PulseAudio";
|
||||
apiMap[RtAudio::LINUX_OSS] = "Linux OSS";
|
||||
apiMap[RtAudio::RTAUDIO_DUMMY] = "RtAudio Dummy";
|
||||
|
||||
std::vector< RtAudio::Api > apis;
|
||||
RtAudio::getCompiledApi(apis);
|
||||
|
||||
qInfo(logAudio()) << "RtAudio Version " << QString::fromStdString(RtAudio::getVersion());
|
||||
|
||||
qInfo(logAudio()) << "Compiled APIs:";
|
||||
for (unsigned int i = 0; i < apis.size(); i++) {
|
||||
qInfo(logAudio()) << " " << QString::fromStdString(apiMap[apis[i]]);
|
||||
}
|
||||
|
||||
RtAudio::DeviceInfo info;
|
||||
|
||||
qInfo(logAudio()) << "Current API: " << QString::fromStdString(apiMap[audio->getCurrentApi()]);
|
||||
|
||||
unsigned int devices = audio->getDeviceCount();
|
||||
qInfo(logAudio()) << "Found " << devices << " audio device(s) *=default";
|
||||
|
||||
for (unsigned int i = 1; i < devices; i++) {
|
||||
info = audio->getDeviceInfo(i);
|
||||
if (info.outputChannels > 0) {
|
||||
qInfo(logAudio()) << (info.isDefaultOutput ? "*" : " ") << "(" << i << ") Output Device : " << QString::fromStdString(info.name);
|
||||
ui->audioOutputCombo->addItem(QString::fromStdString(info.name), i);
|
||||
ui->serverTXAudioOutputCombo->addItem(QString::fromStdString(info.name), i);
|
||||
}
|
||||
if (info.inputChannels > 0) {
|
||||
qInfo(logAudio()) << (info.isDefaultInput ? "*" : " ") << "(" << i << ") Input Device : " << QString::fromStdString(info.name);
|
||||
ui->audioInputCombo->addItem(QString::fromStdString(info.name), i);
|
||||
ui->serverRXAudioInputCombo->addItem(QString::fromStdString(info.name), i);
|
||||
}
|
||||
}
|
||||
|
||||
delete audio;
|
||||
|
||||
#elif defined(PORTAUDIO)
|
||||
// Use PortAudio device enumeration
|
||||
|
||||
PaError err;
|
||||
|
||||
err = Pa_Initialize();
|
||||
|
||||
if (err != paNoError)
|
||||
{
|
||||
qInfo(logAudio()) << "ERROR: Cannot initialize Portaudio";
|
||||
}
|
||||
|
||||
qInfo(logAudio()) << "PortAudio version: " << Pa_GetVersionInfo()->versionText;
|
||||
|
||||
int numDevices;
|
||||
numDevices = Pa_GetDeviceCount();
|
||||
qInfo(logAudio()) << "Pa_CountDevices returned" << numDevices;
|
||||
|
||||
const PaDeviceInfo* info;
|
||||
for (int i = 0; i < numDevices; i++)
|
||||
{
|
||||
info = Pa_GetDeviceInfo(i);
|
||||
if (info->maxInputChannels > 0) {
|
||||
qInfo(logAudio()) << (i == Pa_GetDefaultInputDevice() ? "*" : " ") << "(" << i << ") Output Device : " << info->name;
|
||||
ui->audioInputCombo->addItem(info->name, i);
|
||||
ui->serverRXAudioInputCombo->addItem(info->name, i);
|
||||
}
|
||||
if (info->maxOutputChannels > 0) {
|
||||
qInfo(logAudio()) << (i == Pa_GetDefaultOutputDevice() ? "*" : " ") << "(" << i << ") Input Device : " << info->name;
|
||||
ui->audioOutputCombo->addItem(info->name, i);
|
||||
ui->serverTXAudioOutputCombo->addItem(info->name, i);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
// If no external library is configured, use QTMultimedia
|
||||
// Enumerate audio devices, need to do before settings are loaded.
|
||||
qDebug(logSystem()) << "Finding audio input devices";
|
||||
qDebug(logSystem()) << "Finding audio output devices";
|
||||
const auto audioOutputs = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput);
|
||||
for (const QAudioDeviceInfo& deviceInfo : audioOutputs) {
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -1174,7 +1078,7 @@ void wfmain::setAudioDevicesUI()
|
|||
#endif
|
||||
}
|
||||
|
||||
qDebug(logSystem()) << "Finding audio output devices";
|
||||
qDebug(logSystem()) << "Finding audio input devices";
|
||||
const auto audioInputs = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
for (const QAudioDeviceInfo& deviceInfo : audioInputs) {
|
||||
#ifdef Q_OS_WIN
|
||||
|
@ -1190,10 +1094,7 @@ void wfmain::setAudioDevicesUI()
|
|||
qDebug(logSystem()) << "Audio devices done.";
|
||||
rxSetup.port = QAudioDeviceInfo::defaultOutputDevice();
|
||||
txSetup.port = QAudioDeviceInfo::defaultInputDevice();
|
||||
serverRxSetup.port = txSetup.port;
|
||||
serverTxSetup.port = rxSetup.port;
|
||||
qDebug(logSystem()) << "Audio set to default device initially";
|
||||
#endif
|
||||
}
|
||||
|
||||
void wfmain::setSerialDevicesUI()
|
||||
|
@ -1637,14 +1538,10 @@ void wfmain::loadSettings()
|
|||
int audioOutputIndex = ui->audioOutputCombo->findText(rxSetup.name);
|
||||
if (audioOutputIndex != -1) {
|
||||
ui->audioOutputCombo->setCurrentIndex(audioOutputIndex);
|
||||
#if defined(RTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(audioOutputIndex).toInt();
|
||||
#else
|
||||
|
||||
QVariant v = ui->audioOutputCombo->currentData();
|
||||
rxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
}
|
||||
ui->audioOutputCombo->blockSignals(false);
|
||||
|
||||
|
@ -1654,14 +1551,10 @@ void wfmain::loadSettings()
|
|||
int audioInputIndex = ui->audioInputCombo->findText(txSetup.name);
|
||||
if (audioInputIndex != -1) {
|
||||
ui->audioInputCombo->setCurrentIndex(audioInputIndex);
|
||||
#if defined(RTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(audioInputIndex).toInt();
|
||||
#else
|
||||
|
||||
QVariant v = ui->audioInputCombo->currentData();
|
||||
txSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
}
|
||||
ui->audioInputCombo->blockSignals(false);
|
||||
|
||||
|
@ -1717,7 +1610,7 @@ void wfmain::loadSettings()
|
|||
|
||||
RIGCONFIG* rigTemp = new RIGCONFIG();
|
||||
rigTemp->rxAudioSetup.isinput = true;
|
||||
rigTemp->txAudioSetup.isinput = true;
|
||||
rigTemp->txAudioSetup.isinput = false;
|
||||
rigTemp->rxAudioSetup.localAFgain = 255;
|
||||
rigTemp->txAudioSetup.localAFgain = 255;
|
||||
rigTemp->rxAudioSetup.resampleQuality = 4;
|
||||
|
@ -1742,14 +1635,10 @@ void wfmain::loadSettings()
|
|||
int serverAudioInputIndex = ui->serverRXAudioInputCombo->findText(rigTemp->rxAudioSetup.name);
|
||||
if (serverAudioInputIndex != -1) {
|
||||
ui->serverRXAudioInputCombo->setCurrentIndex(serverAudioInputIndex);
|
||||
#if defined(RTAUDIO)
|
||||
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(serverAudioInputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(serverAudioInputIndex).toInt();
|
||||
#else
|
||||
|
||||
QVariant v = ui->serverRXAudioInputCombo->currentData();
|
||||
rigTemp->rxAudioSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
}
|
||||
ui->serverRXAudioInputCombo->blockSignals(false);
|
||||
|
||||
|
@ -1759,17 +1648,12 @@ void wfmain::loadSettings()
|
|||
int serverAudioOutputIndex = ui->serverTXAudioOutputCombo->findText(rigTemp->txAudioSetup.name);
|
||||
if (serverAudioOutputIndex != -1) {
|
||||
ui->serverTXAudioOutputCombo->setCurrentIndex(serverAudioOutputIndex);
|
||||
#if defined(RTAUDIO)
|
||||
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(serverAudioOutputIndex).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(serverAudioOutputIndex).toInt();
|
||||
#else
|
||||
|
||||
QVariant v = ui->serverTXAudioOutputCombo->currentData();
|
||||
rigTemp->txAudioSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
}
|
||||
ui->serverTXAudioOutputCombo->blockSignals(false);
|
||||
|
||||
serverConfig.rigs.append(rigTemp);
|
||||
|
||||
int row = 0;
|
||||
|
@ -1910,30 +1794,25 @@ void wfmain::on_serverAudioPortText_textChanged(QString text)
|
|||
|
||||
void wfmain::on_serverRXAudioInputCombo_currentIndexChanged(int value)
|
||||
{
|
||||
#if defined(RTAUDIO)
|
||||
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
serverRxSetup.port = ui->serverRXAudioInputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->serverRXAudioInputCombo->itemData(value);
|
||||
serverRxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
serverRxSetup.name = ui->serverRXAudioInputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default server audio input to:" << serverRxSetup.name;
|
||||
if (serverConfig.rigs.size() > 0)
|
||||
{
|
||||
QVariant v = ui->serverRXAudioInputCombo->itemData(value);
|
||||
serverConfig.rigs.first()->rxAudioSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
||||
serverConfig.rigs.first()->rxAudioSetup.name = ui->serverRXAudioInputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default server audio input to:" << serverConfig.rigs.first()->rxAudioSetup.name;
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::on_serverTXAudioOutputCombo_currentIndexChanged(int value)
|
||||
{
|
||||
#if defined(RTAUDIO)
|
||||
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
serverTxSetup.port = ui->serverTXAudioOutputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->serverTXAudioOutputCombo->itemData(value);
|
||||
serverTxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
serverTxSetup.name = ui->serverTXAudioOutputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default server audio output to:" << serverTxSetup.name;
|
||||
if (serverConfig.rigs.size() > 0) {
|
||||
QVariant v = ui->serverTXAudioOutputCombo->itemData(value);
|
||||
serverConfig.rigs.first()->txAudioSetup.port = v.value<QAudioDeviceInfo>();
|
||||
|
||||
serverConfig.rigs.first()->txAudioSetup.name = ui->serverTXAudioOutputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default server audio output to:" << serverConfig.rigs.first()->txAudioSetup.name;
|
||||
}
|
||||
}
|
||||
|
||||
void wfmain::on_serverUsersTable_cellChanged(int row, int column)
|
||||
|
@ -2097,8 +1976,8 @@ void wfmain::saveSettings()
|
|||
settings->setValue("ServerControlPort", serverConfig.controlPort);
|
||||
settings->setValue("ServerCivPort", serverConfig.civPort);
|
||||
settings->setValue("ServerAudioPort", serverConfig.audioPort);
|
||||
settings->setValue("ServerAudioOutput", serverTxSetup.name);
|
||||
settings->setValue("ServerAudioInput", serverRxSetup.name);
|
||||
settings->setValue("ServerAudioOutput", serverConfig.rigs.first()->txAudioSetup.name);
|
||||
settings->setValue("ServerAudioInput", serverConfig.rigs.first()->rxAudioSetup.name);
|
||||
|
||||
/* Remove old format users*/
|
||||
int numUsers = settings->value("ServerNumUsers", 0).toInt();
|
||||
|
@ -3343,6 +3222,12 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
|
|||
|
||||
this->rigCaps = rigCaps;
|
||||
rigName->setText(rigCaps.modelName);
|
||||
if (serverConfig.enabled) {
|
||||
serverConfig.rigs.first()->modelName = rigCaps.modelName;
|
||||
serverConfig.rigs.first()->rigName = rigCaps.modelName;
|
||||
serverConfig.rigs.first()->civAddr = rigCaps.civ;
|
||||
serverConfig.rigs.first()->baudRate = rigCaps.baudRate;
|
||||
}
|
||||
setWindowTitle(rigCaps.modelName);
|
||||
this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true.
|
||||
haveRigCaps = true;
|
||||
|
@ -4734,28 +4619,18 @@ void wfmain::on_passwordTxt_textChanged(QString text)
|
|||
|
||||
void wfmain::on_audioOutputCombo_currentIndexChanged(int value)
|
||||
{
|
||||
#if defined(RTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
rxSetup.port = ui->audioOutputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioOutputCombo->itemData(value);
|
||||
rxSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
rxSetup.name = ui->audioOutputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default audio output to:" << rxSetup.name;
|
||||
}
|
||||
|
||||
void wfmain::on_audioInputCombo_currentIndexChanged(int value)
|
||||
{
|
||||
#if defined(RTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
|
||||
#elif defined(PORTAUDIO)
|
||||
txSetup.port = ui->audioInputCombo->itemData(value).toInt();
|
||||
#else
|
||||
QVariant v = ui->audioInputCombo->itemData(value);
|
||||
txSetup.port = v.value<QAudioDeviceInfo>();
|
||||
#endif
|
||||
|
||||
txSetup.name = ui->audioInputCombo->itemText(value);
|
||||
qDebug(logGui()) << "Changed default audio input to:" << txSetup.name;
|
||||
}
|
||||
|
|
2
wfmain.h
2
wfmain.h
|
@ -780,8 +780,6 @@ private:
|
|||
audioSetup rxSetup;
|
||||
audioSetup txSetup;
|
||||
|
||||
audioSetup serverRxSetup;
|
||||
audioSetup serverTxSetup;
|
||||
|
||||
colors defaultColors;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue