diff --git a/.github/workflows/ci-windows-build.yml b/.github/workflows/ci-windows-build.yml index 51dca61..ed4aef8 100644 --- a/.github/workflows/ci-windows-build.yml +++ b/.github/workflows/ci-windows-build.yml @@ -20,7 +20,7 @@ jobs: with: msystem: MINGW64 update: true - install: git mingw-w64-x86_64-toolchain autoconf libtool mingw-w64-x86_64-cpputest mingw-w64-x86_64-qt5 mingw-w64-x86_64-cmake mingw-w64-x86_64-libvorbis zip p7zip unzip + install: git mingw-w64-x86_64-toolchain autoconf libtool mingw-w64-x86_64-cpputest mingw-w64-x86_64-qt5 mingw-w64-x86_64-cmake mingw-w64-x86_64-libvorbis mingw-w64-x86_64-zeromq zip p7zip unzip # build for windows - name: Windows-CI-Build if: ${{ matrix.os == 'windows-latest' }} diff --git a/.gitignore b/.gitignore index ff69e0f..281a0c8 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,8 @@ qrc_*.cpp Thumbs.db *.res *.rc -/.qmake.cache -/.qmake.stash +.qmake.cache +.qmake.stash # qtcreator generated files *.pro.user* diff --git a/JAERO/JAERO.pro b/JAERO/JAERO.pro index deaef90..e4be479 100644 --- a/JAERO/JAERO.pro +++ b/JAERO/JAERO.pro @@ -11,7 +11,7 @@ #if you are having trubbles focus on things like "LIBS += -L$$OGG_PATH/src/.libs" #remember to compile libvorbis,libogg, and libcorrect before compiling this -DEFINES += JAERO_VERSION=\\\"v1.0.4.12-alpha\\\" +DEFINES += JAERO_VERSION=\\\"v1.0.4.13-alpha\\\" QT += multimedia core network gui svg sql @@ -85,7 +85,10 @@ SOURCES += mainwindow.cpp \ $$JFFT_PATH/jfft.cpp \ util/stdio_utils.cpp \ util/file_utils.cpp \ - util/RuntimeError.cpp + util/RuntimeError.cpp \ + zmq_audiosender.cpp \ + zmq_audioreceiver.cpp + HEADERS += mainwindow.h \ coarsefreqestimate.h \ @@ -119,17 +122,20 @@ HEADERS += mainwindow.h \ $$JFFT_PATH/jfft.h \ util/stdio_utils.h \ util/file_utils.h \ - util/RuntimeError.h + util/RuntimeError.h \ + zmq_audioreceiver.h \ + zmq_audiosender.h + # Tell the qcustomplot header that it will be used as library: DEFINES += QCUSTOMPLOT_USE_LIBRARY #qcustom plot is called different names on different systems win32 { #message("windows") -LIBS += -lqcustomplot2 +LIBS += -lqcustomplot2 -llibzmq } else { #message("not windows") -LIBS += -lqcustomplot +LIBS += -lqcustomplot -lzmq } FORMS += mainwindow.ui \ @@ -159,7 +165,7 @@ QMAKE_CXXFLAGS_RELEASE += -O3 #QMAKE_CXXFLAGS_RELEASE *= -O3 #for static building order seems to matter -LIBS += -lcorrect -lvorbis -lvorbisenc -logg -lacars +LIBS += -lcorrect -lvorbis -lvorbisenc -logg -lacars #desktop desktop.path = /usr/share/applications diff --git a/JAERO/aerol.cpp b/JAERO/aerol.cpp index 646a93f..0cf6c09 100644 --- a/JAERO/aerol.cpp +++ b/JAERO/aerol.cpp @@ -1407,8 +1407,6 @@ QByteArray &AeroL::Decode(QVector &bits, bool soft)//0 bit --> oldest bit uchar SEQINDICATOR=((byte1&0xF0)>>4); uchar SUTYPE=byte1&0x0F; - uchar QNO=((byte2&0xF0)>>4); - uchar REFNO=byte2&0x07; quint32 AESID=byte3<<8*2|byte4<<8*1|byte5<<8*0; int GES=byte6; @@ -1446,8 +1444,6 @@ QByteArray &AeroL::Decode(QVector &bits, bool soft)//0 bit --> oldest bit int BytesInSU=0; if((SUTYPE>=1)&&(SUTYPE<=11))BytesInSU=SUTYPE; - bool SignalingInfoSU=false; - if(SUTYPE==15)SignalingInfoSU=true; decline+=((QString)" SU %1 of %2. AES: %3 GES: %4").arg(SUindex+1).arg(SUTotal).arg((((QString)"%1").arg(AESID,6, 16, QChar('0'))).toUpper()).arg((((QString)"%1").arg(GES,2, 16, QChar('0'))).toUpper()) ; /*decline+=" \""; @@ -1735,6 +1731,10 @@ QByteArray &AeroL::Decode(QVector &bits, bool soft)//0 bit --> oldest bit break; case Log_on_confirm: decline+="Log_on_confirm"; + + { + SendLogOnOff(k, "Log on confirm"); + } break; case Log_control_P_channel_log_off_request: decline+="Log_control_P_channel_log_off_request"; @@ -2166,9 +2166,21 @@ void AeroL::SendCAssignment(int k, QString decline) QString beam = " Global Beam "; if(byte7&0x80)beam=" Spot Beam "; + item.message = "Receive Freq: " + receive + beam + "Transmit " + transmit + "\r\n" + decline; + emit ACARSsignal(item); +} +void AeroL::SendLogOnOff(int k, QString text) +{ + ACARSItem item; + item.isuitem.AESID=((uchar)infofield[k*12-1+2])<<8*2|((uchar)infofield[k*12-1+3])<<8*1|((uchar)infofield[k*12-1+4])<<8*0; + item.isuitem.GESID=infofield[k*12-1+5]; + item.hastext = true; + item.downlink = true; + item.nonacars = true; + item.valid = true; - item.message = "Receive Freq: " + receive + beam + "Transmit " + transmit + "\r\n" + decline; + item.message = text; emit ACARSsignal(item); } @@ -2182,6 +2194,8 @@ QByteArray &AeroL::DecodeC(QVector &bits) quint16 bit=0; quint16 soft_bit=0; + QString hex = "000000"; + for(int i=0;i &bits) decline+=" GES = "+infofield.mid(4,1).toHex().toUpper(); decline+=" Call_progress \r\n"; emit Call_progress_Signal(infofield); + + QString thex = infofield.mid(1,3).toHex().toUpper(); + + if(thex.length() == 6) + { + hex = thex; + } + } break; @@ -2457,13 +2479,15 @@ QByteArray &AeroL::DecodeC(QVector &bits) } } + // send for external decoding + emit Voicesignal(data, hex); + //25 primary fields. this is where the audio lives in a compressed format for(int i=0;i<25;i++) { - emit Voicesignal(data.mid(i*12,12));//send one frame at a time + emit Voicesignal(data.mid(i*12,12));//send one frame at a time } - // reset for next block index = -1; }// end of frame diff --git a/JAERO/aerol.h b/JAERO/aerol.h index 34277f9..c90963b 100644 --- a/JAERO/aerol.h +++ b/JAERO/aerol.h @@ -397,26 +397,47 @@ class AeroLScrambler public: AeroLScrambler() { - reset(); - } - void reset() - { + QVector state; + position=0; + pre_state.resize(5000); int tmp[]={1,1,0,1,0,0,1,0,1,0,1,1,0,0,1,-1}; state.clear(); for(int i=0;tmp[i]>=0;i++)state.push_back(tmp[i]); + + + // populate the vector so we can reuse it + for(int a = 0; a<5000;a++) + { + + int val0 = state.at(0)^state.at(14); + pre_state[a]=val0; + for(int i=state.size()-1;i>0;i--) + { + state[i]=state.at(i-1); + } + state[0] =val0; + + } } + void update(QVector &data) { for(int j=0;j0;i--)state[i]=state.at(i-1); - state[0]=val0; + data[j] = data.at(j)^pre_state.at(position); + position++; } + + } + void reset() + { + + position = 0; } private: - QVector state; + + QVector pre_state; + int position; }; class PuncturedCode @@ -626,7 +647,7 @@ class RTChannelDeleaveFECScram bool cont = false; - if((((blockptr-(64*5))%(64*3))==0) && (blockptr /64 == 5 || blockptr /64 == targetBlocks || blockptr/64 == 8 || blockptr/64 == 50)) + if((((blockptr-(64*5))%(64*3))==0) && (blockptr /64 == 5 || blockptr /64 == targetBlocks || blockptr/64 == 11 || blockptr/64 == 50)) { cont = true; } @@ -666,6 +687,10 @@ class RTChannelDeleaveFECScram lastpacketstate=OK_R_Packet; return OK_R_Packet; + }else{ + + return Nothing; + } } @@ -682,11 +707,7 @@ class RTChannelDeleaveFECScram else { - if(blockptr/64 ==5){ - return Nothing; - } - - if(blockptr/64 == 8){ + if(blockptr/64 == 11){ // we should be able to peek at the SU after the initial SU and figure out the number of SU's in this // burst @@ -703,7 +724,7 @@ class RTChannelDeleaveFECScram } - targetBlocks = (targetSUSize*3) +2; + targetBlocks = ((targetSUSize+1)*3) +2; return Nothing; } @@ -711,7 +732,7 @@ class RTChannelDeleaveFECScram // this should be the target blocks for this T packet if(blockptr/64 == targetBlocks) { - for(int i=0;i &bits, bool soft = false); QByteArray &DecodeC(QVector &bits); diff --git a/JAERO/audioburstmskdemodulator.cpp b/JAERO/audioburstmskdemodulator.cpp index 01e8566..1549c88 100644 --- a/JAERO/audioburstmskdemodulator.cpp +++ b/JAERO/audioburstmskdemodulator.cpp @@ -3,16 +3,19 @@ #include AudioBurstMskDemodulator::AudioBurstMskDemodulator(QObject *parent) -: BurstMskDemodulator(parent), - m_audioInput(NULL) + : BurstMskDemodulator(parent), + m_audioInput(NULL) { -// + // } void AudioBurstMskDemodulator::start() { BurstMskDemodulator::start(); - if(m_audioInput)m_audioInput->start(this); + if(!settings.zmqAudio) + { + if(m_audioInput)m_audioInput->start(this); + } } void AudioBurstMskDemodulator::stop() diff --git a/JAERO/audioburstoqpskdemodulator.cpp b/JAERO/audioburstoqpskdemodulator.cpp index 789650f..2b482d9 100644 --- a/JAERO/audioburstoqpskdemodulator.cpp +++ b/JAERO/audioburstoqpskdemodulator.cpp @@ -2,8 +2,8 @@ #include AudioBurstOqpskDemodulator::AudioBurstOqpskDemodulator(QObject *parent) -: BurstOqpskDemodulator(parent), - m_audioInput(NULL) + : BurstOqpskDemodulator(parent), + m_audioInput(NULL) { demod2=new BurstOqpskDemodulator(this); demod2->channel_select_other=true; @@ -15,7 +15,10 @@ void AudioBurstOqpskDemodulator::start() { BurstOqpskDemodulator::start(); demod2->start(); - if(m_audioInput)m_audioInput->start(this); + if(!settings.zmqAudio) + { + if(m_audioInput)m_audioInput->start(this); + } } void AudioBurstOqpskDemodulator::stop() @@ -40,7 +43,7 @@ void AudioBurstOqpskDemodulator::setSettings(Settings _settings) //set the format m_format.setSampleRate(settings.Fs); if(settings.channel_stereo)m_format.setChannelCount(2); - else m_format.setChannelCount(1); + else m_format.setChannelCount(1); m_format.setSampleSize(16); m_format.setCodec("audio/pcm"); m_format.setByteOrder(QAudioFormat::LittleEndian); diff --git a/JAERO/audiomskdemodulator.cpp b/JAERO/audiomskdemodulator.cpp index ba19a28..9329d43 100644 --- a/JAERO/audiomskdemodulator.cpp +++ b/JAERO/audiomskdemodulator.cpp @@ -3,16 +3,19 @@ #include AudioMskDemodulator::AudioMskDemodulator(QObject *parent) -: MskDemodulator(parent), - m_audioInput(NULL) + : MskDemodulator(parent), + m_audioInput(NULL) { -// + // } void AudioMskDemodulator::start() { MskDemodulator::start(); - if(m_audioInput)m_audioInput->start(this); + if(!settings.zmqAudio) + { + if(m_audioInput)m_audioInput->start(this); + } } void AudioMskDemodulator::stop() diff --git a/JAERO/audiooqpskdemodulator.cpp b/JAERO/audiooqpskdemodulator.cpp index 54645d0..adab832 100644 --- a/JAERO/audiooqpskdemodulator.cpp +++ b/JAERO/audiooqpskdemodulator.cpp @@ -3,16 +3,21 @@ #include AudioOqpskDemodulator::AudioOqpskDemodulator(QObject *parent) -: OqpskDemodulator(parent), - m_audioInput(NULL) + : OqpskDemodulator(parent), + m_audioInput(NULL) { -// + // } void AudioOqpskDemodulator::start() { OqpskDemodulator::start(); - if(m_audioInput)m_audioInput->start(this); + + if(!settings.zmqAudio) + { + if(m_audioInput)m_audioInput->start(this); + } + } void AudioOqpskDemodulator::stop() diff --git a/JAERO/burstmskdemodulator.cpp b/JAERO/burstmskdemodulator.cpp index 060b44e..26efcca 100644 --- a/JAERO/burstmskdemodulator.cpp +++ b/JAERO/burstmskdemodulator.cpp @@ -127,7 +127,10 @@ void BurstMskDemodulator::setSQL(bool state) { sql=state; } - +void BurstMskDemodulator::setCPUReduce(bool state) +{ + cpuReduce=state; +} void BurstMskDemodulator::setScatterPointType(ScatterPointType type) { scatterpointtype=type; @@ -395,7 +398,8 @@ qint64 BurstMskDemodulator::writeData(const char *data, qint64 len) if(fabs(dval)>maxval)maxval=fabs(dval); spectrumcycbuff[spectrumcycbuff_ptr]=dval; spectrumcycbuff_ptr++;spectrumcycbuff_ptr%=spectrumnfft; - if(timer.elapsed()>150) + //if(timer.elapsed()>150) + if((!cpuReduce && timer.elapsed()>150) || (cpuReduce && timer.elapsed()>1000)) { timer.start(); emit OrgOverlapedBuffer(spectrumcycbuff); @@ -592,152 +596,157 @@ qint64 BurstMskDemodulator::writeData(const char *data, qint64 len) } - cval= mixer2.WTCISValue()*(val_to_demod)*vol_gain; - - cpx_type sig2 = cpx_type(matchedfilter_re->FIRUpdateAndProcess(cval.real()),matchedfilter_im->FIRUpdateAndProcess(cval.imag())); - - if(cntr>(startProcessing*SamplesPerSymbol) && cntr 0 || mse < signalthreshold) { - cpx_type symboltone_pt=sig2*symboltone_rotator*imag; - double er=std::tanh(symboltone_pt.imag())*(symboltone_pt.real()); - symboltone_rotator=symboltone_rotator*std::exp(imag*er*0.5); - symboltone_averotator=symboltone_averotator*0.999+0.001*symboltone_rotator; + cval= mixer2.WTCISValue()*(val_to_demod)*vol_gain; - symboltone_pt=cpx_type((symboltone_pt.real()),a1.update(symboltone_pt.real())); + cpx_type sig2 = cpx_type(matchedfilter_re->FIRUpdateAndProcess(cval.real()),matchedfilter_im->FIRUpdateAndProcess(cval.imag())); - double progress = (double)cntr-(SamplesPerSymbol*(startProcessing)); - double goal = endRotation-(SamplesPerSymbol*startProcessing); - progress = progress/goal; + if(cntr>(startProcessing*SamplesPerSymbol) && cntrUpdate(std::abs(sig2)); + st_err*=0.5*(1.0-progress*progress); + st_osc_half.AdvanceFractionOfWave(-(1.0/(2.0*M_PI))*st_err*0.05); + st_osc.SetPhaseDeg(st_osc_half.GetPhaseDeg()+(360.0*(1.0-ee))); + } - //send ebno when right time - if(cntr== endRotation + (200*SamplesPerSymbol)) - { - emit EbNoMeasurmentSignal(ebnomeasure->EbNo); - } + sig2*=symboltone_averotator; + rotator=rotator*std::exp(imag*rotator_freq); + sig2*=rotator; - //AGC - sig2*=agc2->Update(std::abs(sig2)); - //clipping - double abval=std::abs(sig2); - if(abval>2.84)sig2=(2.84/abval)*sig2; + //Measure ebno + ebnomeasure->Update(std::abs(sig2)); - //normal symbol timer - cpx_type pt_d = delayedsmpl.update_dont_touch(sig2); - cpx_type pt_msk=cpx_type(sig2.real(), pt_d.imag()); + //send ebno when right time + if(cntr== endRotation + (200*SamplesPerSymbol)) + { + emit EbNoMeasurmentSignal(ebnomeasure->EbNo); + } - double st_eta = std::abs(pt_msk); - st_eta=st_iir_resonator.update(st_eta); + //AGC + sig2*=agc2->Update(std::abs(sig2)); - cpx_type st_m1=cpx_type(st_eta,-delayt8.update(st_eta)); - cpx_type st_out=st_osc.WTCISValue()*st_m1; + //clipping + double abval=std::abs(sig2); + if(abval>2.84)sig2=(2.84/abval)*sig2; - double st_angle_error=std::arg(st_out); - //acquire the symbol oscillation - if(cntr>endRotation) - { - st_osc.AdvanceFractionOfWave(-st_angle_error*0.002/360.0); - } + //normal symbol timer + cpx_type pt_d = delayedsmpl.update_dont_touch(sig2); + cpx_type pt_msk=cpx_type(sig2.real(), pt_d.imag()); - //sample times - if(st_osc.IfHavePassedPoint(ee)) - { + double st_eta = std::abs(pt_msk); + st_eta=st_iir_resonator.update(st_eta); - //carrier tracking - double ct_xt=tanh(sig2.imag())*sig2.real(); - double ct_xt_d=tanh(pt_d.real())*pt_d.imag(); + cpx_type st_m1=cpx_type(st_eta,-delayt8.update(st_eta)); + cpx_type st_out=st_osc.WTCISValue()*st_m1; - double ct_ec=ct_xt_d-ct_xt; - if(ct_ec>M_PI)ct_ec=M_PI; - if(ct_ec<-M_PI)ct_ec=-M_PI; - if(ct_ec>M_PI_2)ct_ec=M_PI_2; - if(ct_ec<-M_PI_2)ct_ec=-M_PI_2; - if(cntr>(startProcessing*SamplesPerSymbol)) + double st_angle_error=std::arg(st_out); + //acquire the symbol oscillation + if(cntr>endRotation) { - rotator=rotator*std::exp(imag*ct_ec*0.25);//correct carrier phase - if(cntr>endRotation) - { - rotator_freq=rotator_freq+ct_ec*0.0001;//correct carrier frequency - } + st_osc.AdvanceFractionOfWave(-st_angle_error*0.002/360.0); } - //gui feedback - if(cntr >= (endRotation + 100*SamplesPerSymbol) && pointbuff_ptrM_PI)ct_ec=M_PI; + if(ct_ec<-M_PI)ct_ec=-M_PI; + if(ct_ec>M_PI_2)ct_ec=M_PI_2; + if(ct_ec<-M_PI_2)ct_ec=-M_PI_2; + if(cntr>(startProcessing*SamplesPerSymbol)) + { + rotator=rotator*std::exp(imag*ct_ec*0.25);//correct carrier phase + if(cntr>endRotation) + { + rotator_freq=rotator_freq+ct_ec*0.0001;//correct carrier frequency + } + } + + //gui feedback + if(cntr >= (endRotation + 100*SamplesPerSymbol) && pointbuff_ptr(startProcessing*SamplesPerSymbol)) { - pointbuff_ptr++; - emit ScatterPoints(pointbuff); + double tda=(fabs((pt_msk*0.75).real())-1.0); + double tdb=(fabs((pt_msk*0.75).imag())-1.0); + mse=msema->Update((tda*tda)+(tdb*tdb)); } - } - //calc MSE of the points - if(cntr>(startProcessing*SamplesPerSymbol)) - { - double tda=(fabs((pt_msk*0.75).real())-1.0); - double tdb=(fabs((pt_msk*0.75).imag())-1.0); - mse=msema->Update((tda*tda)+(tdb*tdb)); - } + //soft bits + double imagin = diffdecode.UpdateSoft(pt_msk.imag()); - //soft bits - double imagin = diffdecode.UpdateSoft(pt_msk.imag()); + int ibit=qRound((imagin)*127.0+128.0); + if(ibit>255)ibit=255; + if(ibit<0)ibit=0; - int ibit=qRound((imagin)*127.0+128.0); - if(ibit>255)ibit=255; - if(ibit<0)ibit=0; + RxDataBits.push_back((uchar)ibit); - RxDataBits.push_back((uchar)ibit); + double real = diffdecode.UpdateSoft(pt_msk.real()); - double real = diffdecode.UpdateSoft(pt_msk.real()); + real =- real; - real =- real; + ibit=qRound((real)*127.0+128.0); - ibit=qRound((real)*127.0+128.0); + if(ibit>255)ibit=255; + if(ibit<0)ibit=0; - if(ibit>255)ibit=255; - if(ibit<0)ibit=0; + RxDataBits.push_back((uchar)ibit); - RxDataBits.push_back((uchar)ibit); + // push them out to decode + if(RxDataBits.size() >= 12) + { + emit processDemodulatedSoftBits(RxDataBits); + RxDataBits.clear(); + } - // push them out to decode - if(RxDataBits.size() >= 12) - { - emit processDemodulatedSoftBits(RxDataBits); - RxDataBits.clear(); } - } + st_osc.WTnextFrame(); + st_osc_half.WTnextFrame(); - st_osc.WTnextFrame(); - st_osc_half.WTnextFrame(); + mixer2.WTnextFrame(); + mixer_center.WTnextFrame(); - mixer2.WTnextFrame(); - mixer_center.WTnextFrame(); + } } return len; @@ -750,3 +759,11 @@ void BurstMskDemodulator::DCDstatSlot(bool _dcd) dcd=_dcd; } +void BurstMskDemodulator::dataReceived(const QByteArray &audio,quint32 sampleRate) +{ + if(sampleRate!=Fs) + { + qDebug()<<"Sample rate not supported by demodulator"; + } + writeData(audio, audio.length()); +} diff --git a/JAERO/burstmskdemodulator.h b/JAERO/burstmskdemodulator.h index cf74586..bf3f6c2 100644 --- a/JAERO/burstmskdemodulator.h +++ b/JAERO/burstmskdemodulator.h @@ -33,6 +33,7 @@ class BurstMskDemodulator : public QIODevice double Fs; int symbolspercycle; double signalthreshold; + bool zmqAudio; Settings() { coarsefreqest_fft_power=13;//2^coarsefreqest_fft_power @@ -42,6 +43,7 @@ class BurstMskDemodulator : public QIODevice Fs=8000;//Hz symbolspercycle=16; signalthreshold=0.6; + zmqAudio=false; } }; explicit BurstMskDemodulator(QObject *parent); @@ -58,6 +60,7 @@ class BurstMskDemodulator : public QIODevice void invalidatesettings(); void setAFC(bool state); void setSQL(bool state); + void setCPUReduce(bool state); void setScatterPointType(ScatterPointType type); double getCurrentFreq(); private: @@ -140,7 +143,6 @@ class BurstMskDemodulator : public QIODevice //delay for trident detection DelayThing d2; - //trident shape thing QVector tridentbuffer; int tridentbuffer_ptr; @@ -188,6 +190,7 @@ class BurstMskDemodulator : public QIODevice DelayThing delayedsmpl; + bool cpuReduce; signals: void ScatterPoints(const QVector &buffer); @@ -209,6 +212,8 @@ class BurstMskDemodulator : public QIODevice public slots: void CenterFreqChangedSlot(double freq_center); void DCDstatSlot(bool dcd); + void dataReceived(const QByteArray &audio, quint32 sampleRate); + }; diff --git a/JAERO/burstoqpskdemodulator.cpp b/JAERO/burstoqpskdemodulator.cpp index d585011..88fa6f7 100644 --- a/JAERO/burstoqpskdemodulator.cpp +++ b/JAERO/burstoqpskdemodulator.cpp @@ -172,6 +172,12 @@ void BurstOqpskDemodulator::setSQL(bool state) sql=state; } +void BurstOqpskDemodulator::setCPUReduce(bool state) +{ + cpuReduce=state; + +} + void BurstOqpskDemodulator::setScatterPointType(ScatterPointType type) { scatterpointtype=type; @@ -297,6 +303,14 @@ qint64 BurstOqpskDemodulator::writeData(const char *data, qint64 len) return len; } +void BurstOqpskDemodulator::dataReceived(const QByteArray &audio,quint32 sampleRate) +{ + if(sampleRate!=Fs) + { + qDebug()<<"Sample rate not supported by demodulator"; + } + writeData(audio, audio.length()); +} void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) { @@ -342,7 +356,9 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) if(fabs(dval)>maxval)maxval=fabs(dval); spectrumcycbuff[spectrumcycbuff_ptr]=dval; spectrumcycbuff_ptr++;spectrumcycbuff_ptr%=spectrumnfft; - if(timer.elapsed()>150) + + if((!cpuReduce && timer.elapsed()>150) || (cpuReduce && timer.elapsed()>1000)) + { sendscatterpoints=true; timer.start(); @@ -373,7 +389,6 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) if(pdet.update(bt_sig)) { tridentbuffer_ptr=0; - } if(tridentbuffer_ptrZero(); - } - }//end of trident check //mix @@ -512,16 +521,11 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) startstop=startstopstart; } - - } if(startstop==0) { startstop--; - // qDebug()<<"stop"; - emit SignalStatus(false); - } if((cntr>((256-10)*SamplesPerSymbol))&&insertpreamble) @@ -555,27 +559,26 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) //correct carrier phase - sig2*=symboltone_averotator; rotator=rotator*std::exp(imag*rotator_freq); sig2*=rotator; + double sig2abs = std::abs(sig2); + //Measure ebno - ebnomeasure->Update(std::abs(sig2)); + ebnomeasure->Update(sig2abs); //send ebno when right time if(fabs(cntr-((128.0+128.0+128.0)*SamplesPerSymbol))<0.5)emit EbNoMeasurmentSignal(ebnomeasure->EbNo); //AGC - sig2*=agc2->Update(std::abs(sig2)); + sig2*=agc2->Update(sig2abs); //clipping double abval=std::abs(sig2); if(abval>2.84)sig2=(2.84/abval)*sig2; - - //normal symbol timer double st_diff=delays.update(abval*abval)-(abval*abval); double st_d1out=delayt41.update(st_diff); @@ -683,7 +686,7 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) } - //if(startstop>0)//if signal then may as well demodulate + if(startstop>0)//if signal then may as well demodulate { @@ -732,3 +735,4 @@ void BurstOqpskDemodulator::writeDataSlot(const char *data, qint64 len) return; } + diff --git a/JAERO/burstoqpskdemodulator.h b/JAERO/burstoqpskdemodulator.h index ab9a324..db73e5c 100644 --- a/JAERO/burstoqpskdemodulator.h +++ b/JAERO/burstoqpskdemodulator.h @@ -30,6 +30,7 @@ class BurstOqpskDemodulator : public QIODevice double Fs; double signalthreshold; bool channel_stereo; + bool zmqAudio; Settings() { coarsefreqest_fft_power=13;//2^coarsefreqest_fft_power @@ -39,12 +40,14 @@ class BurstOqpskDemodulator : public QIODevice Fs=48000;//Hz signalthreshold=0.6; channel_stereo=false; + zmqAudio=false; } }; explicit BurstOqpskDemodulator(QObject *parent); ~BurstOqpskDemodulator(); void setAFC(bool state); void setSQL(bool state); + void setCPUReduce(bool state); void setSettings(Settings settings); void invalidatesettings(); void ConnectSinkDevice(QIODevice *datasinkdevice); @@ -57,8 +60,7 @@ class BurstOqpskDemodulator : public QIODevice void setScatterPointType(ScatterPointType type); //--L/R channel selection - bool channel_select_other; - // + bool channel_select_other; signals: void ScatterPoints(const QVector &buffer); @@ -213,9 +215,15 @@ class BurstOqpskDemodulator : public QIODevice bool channel_stereo; + bool cpuReduce; + + + public slots: void CenterFreqChangedSlot(double freq_center); void writeDataSlot(const char *data, qint64 len); + void dataReceived(const QByteArray &audio, quint32 sampleRate); + }; diff --git a/JAERO/gui_classes/settingsdialog.cpp b/JAERO/gui_classes/settingsdialog.cpp index e705d09..68f6a3a 100644 --- a/JAERO/gui_classes/settingsdialog.cpp +++ b/JAERO/gui_classes/settingsdialog.cpp @@ -118,6 +118,16 @@ void SettingsDialog::poulatepublicvars() ui->checkTCPAsClient->setEnabled(ui->checkOutputADSMessageToTCP->isChecked()); + localAudioOutEnabled=ui->ambeEnabled->isChecked(); + zmqAudioOutEnabled=ui->remoteAmbeEnabled->isChecked(); + zmqAudioOutBind=ui->lineEditZMQBind->text(); + zmqAudioOutTopic=ui->lineEditZMQBindTopic->text(); + + zmqAudioInputAddress = ui->lineEditZmqConnectAddress->text(); + zmqAudioInputTopic = ui->lineEditZmqTopic->text(); + zmqAudioInputEnabled = ui->checkBoxZMQ->isChecked(); + + } @@ -147,8 +157,27 @@ void SettingsDialog::populatesettings() ui->checkOutputADSMessageToTCP->setChecked(settings.value("checkOutputADSMessageToTCP",false).toBool()); ui->checkTCPAsClient->setChecked(settings.value("checkTCPAsClient",false).toBool()); -//these have been tested so far as lineEditplanelookup -//http://www.flightradar24.com/data/airplanes/{REG} + + ui->ambeEnabled->setChecked(settings.value("localAudioOutEnabled", true).toBool()); + ui->remoteAmbeEnabled->setChecked(settings.value("remoteAudioOutEnabled", false).toBool()); + + + if(!ui->remoteAmbeEnabled->isChecked()) + { + ui->lineEditZMQBind->setEnabled(false); + ui->lineEditZMQBindTopic->setEnabled(false); + + } + ui->lineEditZMQBind->setText(settings.value("remoteAudioOutBindAddress", "tcp://*:5551").toString()); + ui->lineEditZMQBindTopic->setText(settings.value("remoteAudioOutBindTopic", "JAERO").toString()); + + ui->checkBoxZMQ->setChecked(settings.value("zmqAudioInputEnabled", false).toBool()); + ui->lineEditZmqConnectAddress->setText(settings.value("zmqAudioInputReceiveAddress", "tcp://127.0.0.1:6003").toString()); + + + QString default_topic = settings_name.remove(QRegExp( "JAERO \\[" )).remove(QRegExp( "\\]" )); + + ui->lineEditZmqTopic->setText(settings.value("zmqAudioInputReceiveTopic", default_topic).toString()); on_lineEditlogdir_editingFinished(); @@ -176,6 +205,16 @@ void SettingsDialog::accept() settings.setValue("checkOutputADSMessageToTCP", ui->checkOutputADSMessageToTCP->isChecked()); settings.setValue("checkTCPAsClient", ui->checkTCPAsClient->isChecked()); + settings.setValue("localAudioOutEnabled", ui->ambeEnabled->isChecked()); + settings.setValue("remoteAudioOutEnabled", ui->remoteAmbeEnabled->isChecked()); + settings.setValue("remoteAudioOutBindAddress",ui->lineEditZMQBind->text()); + settings.setValue("remoteAudioOutBindTopic",ui->lineEditZMQBindTopic->text()); + + + settings.setValue("zmqAudioInputEnabled", ui->checkBoxZMQ->isChecked()); + settings.setValue("zmqAudioInputReceiveAddress", ui->lineEditZmqConnectAddress->text()); + settings.setValue("zmqAudioInputReceiveTopic", ui->lineEditZmqTopic->text()); + poulatepublicvars(); QDialog::accept(); } diff --git a/JAERO/gui_classes/settingsdialog.h b/JAERO/gui_classes/settingsdialog.h index a4dcd21..177417f 100644 --- a/JAERO/gui_classes/settingsdialog.h +++ b/JAERO/gui_classes/settingsdialog.h @@ -51,6 +51,21 @@ class SettingsDialog : public QDialog bool tcp_for_ads_messages_enabled; bool tcp_as_client_enabled; + + bool cpuSaveMode; + bool disableAcarsConsole; + + bool localAudioOutEnabled; + bool zmqAudioOutEnabled; + QString zmqAudioOutBind; + QString zmqAudioOutTopic; + + bool zmqAudioInputEnabled; + QString zmqAudioInputAddress; + QString zmqAudioInputTopic; + + + private: Ui::SettingsDialog *ui; void poulatepublicvars(); diff --git a/JAERO/gui_classes/settingsdialog.ui b/JAERO/gui_classes/settingsdialog.ui index 973650d..2721f6c 100644 --- a/JAERO/gui_classes/settingsdialog.ui +++ b/JAERO/gui_classes/settingsdialog.ui @@ -2,12 +2,15 @@ SettingsDialog + + Qt::NonModal + 0 0 451 - 665 + 720 @@ -19,13 +22,7 @@ 451 - 665 - - - - - 451 - 665 + 720 @@ -208,17 +205,17 @@ eg "localhost:12345 localhost:12346" 10 470 401 - 101 + 151 - Soundcard + Audio source 10 - 30 + 20 381 22 @@ -227,8 +224,8 @@ eg "localhost:12345 localhost:12346" - 20 - 67 + 10 + 120 321 19 @@ -237,6 +234,95 @@ eg "localhost:12345 localhost:12346" Enable widebandwidth (CPU intensive) + + + + 10 + 50 + 101 + 41 + + + + ZMQ Audio + + + + + + 190 + 60 + 201 + 20 + + + + + + + 120 + 60 + 61 + 25 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + Address + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 130 + 90 + 51 + 25 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + Topic + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + 190 + 90 + 101 + 20 + + + @@ -443,6 +529,132 @@ eg "localhost:12345 localhost:12346" + + + + 8 + 0 + + + + Voice Settings + + + + + 10 + 20 + 401 + 191 + + + + Voice decoding + + + + + 20 + 110 + 121 + 16 + + + + Socket bind address + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + true + + + + 150 + 110 + 221 + 20 + + + + + 0 + 0 + + + + tcp://*:5550 + + + + + + 20 + 30 + 171 + 17 + + + + JAERO voice decoding + + + + + + 20 + 70 + 171 + 17 + + + + Remote voice decoding + + + + + + 20 + 150 + 121 + 16 + + + + Topic + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + true + + + + 150 + 150 + 91 + 20 + + + + + 0 + 0 + + + + JAERO + + + + @@ -497,5 +709,85 @@ eg "localhost:12345 localhost:12346" + + checkBoxZMQ + toggled(bool) + comboBoxsoundcard + setDisabled(bool) + + + 75 + 581 + + + 231 + 641 + + + + + checkBoxZMQ + toggled(bool) + lineEditZmqConnectAddress + setEnabled(bool) + + + 75 + 581 + + + 326 + 580 + + + + + checkBoxZMQ + toggled(bool) + lineEditZmqTopic + setEnabled(bool) + + + 75 + 581 + + + 287 + 610 + + + + + remoteAmbeEnabled + toggled(bool) + lineEditZMQBind + setEnabled(bool) + + + 126 + 129 + + + 281 + 170 + + + + + remoteAmbeEnabled + toggled(bool) + lineEditZMQBindTopic + setEnabled(bool) + + + 126 + 129 + + + 216 + 210 + + + diff --git a/JAERO/jconvolutionalcodec.cpp b/JAERO/jconvolutionalcodec.cpp index 1909cef..d51b81c 100644 --- a/JAERO/jconvolutionalcodec.cpp +++ b/JAERO/jconvolutionalcodec.cpp @@ -200,7 +200,7 @@ QVector &JConvolutionalCodec::Decode_Continuous(QByteArray& soft_bits_in)// return decoded_bits; } -//this is a bit of a hack just to compre soft with hard decoding. paddinglength must be a multiple of 8 + // unpack the re-encoded bytes QVector &JConvolutionalCodec::Decode_Continuous_hard(const QByteArray& soft_bits_in)//0-->-1 128-->0 255-->1 { int k=(2*nparitybits*paddinglength)/8;//msg is padded frount and back both times by paddinglength diff --git a/JAERO/main.cpp b/JAERO/main.cpp index 6035bf0..c2b7346 100644 --- a/JAERO/main.cpp +++ b/JAERO/main.cpp @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) QApplication::setApplicationVersion("1.0.4.4"); QCommandLineParser cmdparser; - cmdparser.setApplicationDescription("Demodulatoe and decode Satcom ACARS"); + cmdparser.setApplicationDescription("Demodulate and decode Satcom ACARS"); cmdparser.addHelpOption(); cmdparser.addVersionOption(); diff --git a/JAERO/mainwindow.cpp b/JAERO/mainwindow.cpp index 09ac8fc..9f6d811 100644 --- a/JAERO/mainwindow.cpp +++ b/JAERO/mainwindow.cpp @@ -21,6 +21,7 @@ MainWindow::MainWindow(QWidget *parent) : ui->setupUi(this); + // Nice with VFO name up on the title. You mean it would be nice with the VFO name? QTimer::singleShot(100, [this]() { setWindowTitle("JAERO "+QString(JAERO_VERSION)); } ); beep=new QSound(":/sounds/beep.wav",this); @@ -28,6 +29,11 @@ MainWindow::MainWindow(QWidget *parent) : //plane logging window planelog = new PlaneLog; + //create zmq audio receiver + zmq_audio_receiver = new ZMQAudioReceiver(this); + //create zmq audio sender + zmq_audio_sender = new ZMQAudioSender(this); + //create areo decoder aerol = new AeroL(this); //Create Aero sink aerol2 = new AeroL(this); //Create Aero sink @@ -76,7 +82,6 @@ MainWindow::MainWindow(QWidget *parent) : //create the burst oqpsk demodulator audioburstoqpskdemodulator = new AudioBurstOqpskDemodulator(this); - //create the burst msk demodulator audioburstmskdemodulator = new AudioBurstMskDemodulator(this); @@ -96,7 +101,6 @@ MainWindow::MainWindow(QWidget *parent) : //connect(&arincparser,SIGNAL(DownlinkBasicReportGroupSignal(DownlinkBasicReportGroup&)),sbs1,SLOT(DownlinkBasicReportGroupSlot(DownlinkBasicReportGroup&))); //connect(&arincparser,SIGNAL(DownlinkEarthReferenceGroupSignal(DownlinkEarthReferenceGroup&)),sbs1,SLOT(DownlinkEarthReferenceGroupSlot(DownlinkEarthReferenceGroup&))); - //default sink is the aerol device audiomskdemodulator->ConnectSinkDevice(aerol); audiooqpskdemodulator->ConnectSinkDevice(aerol); @@ -122,9 +126,6 @@ MainWindow::MainWindow(QWidget *parent) : //connect(ambe,SIGNAL(decoded_signal(QByteArray)),this,SLOT(Voiceslot(QByteArray))); // an example connect(ambe,SIGNAL(decoded_signal(QByteArray)),compresseddiskwriter,SLOT(audioin(QByteArray))); connect(ambe,SIGNAL(decoded_signal(QByteArray)),audioout,SLOT(audioin(QByteArray))); - connect(aerol,SIGNAL(Voicesignal(QByteArray)),ambe,SLOT(to_decode_slot(QByteArray))); - - // compresseddiskwriter->openFileForOutput("e:/delme.ogg"); //statusbar setup freqlabel = new QLabel(); @@ -190,6 +191,7 @@ MainWindow::MainWindow(QWidget *parent) : audiomskdemodulator->setSQL(false); audiomskdemodulator->setSettings(audiomskdemodulatorsettings); audiomskdemodulator->setCPUReduce(ui->actionReduce_CPU->isChecked()); + audiomskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; if(typeofdemodtouse==MSK)audiomskdemodulator->start(); //oqpsk @@ -198,6 +200,7 @@ MainWindow::MainWindow(QWidget *parent) : audiooqpskdemodulator->setSQL(false); audiooqpskdemodulator->setSettings(audiooqpskdemodulatorsettings); audiooqpskdemodulator->setCPUReduce(ui->actionReduce_CPU->isChecked()); + audiooqpskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; if(typeofdemodtouse==OQPSK)audiooqpskdemodulator->start(); //burstoqpsk @@ -205,6 +208,8 @@ MainWindow::MainWindow(QWidget *parent) : audioburstoqpskdemodulatorsettings.freq_center=tmpfreq; audioburstoqpskdemodulator->setSQL(false); audioburstoqpskdemodulator->setSettings(audioburstoqpskdemodulatorsettings); + audioburstoqpskdemodulator->setCPUReduce(ui->actionReduce_CPU->isChecked()); + audioburstoqpskdemodulatorsettings.zmqAudio =settingsdialog->zmqAudioInputEnabled; if(typeofdemodtouse==BURSTOQPSK)audioburstoqpskdemodulator->start(); //burst msk @@ -212,6 +217,8 @@ MainWindow::MainWindow(QWidget *parent) : audioburstmskdemodulatorsettings.freq_center=tmpfreq; audioburstmskdemodulator->setSQL(false); audioburstmskdemodulator->setSettings(audioburstmskdemodulatorsettings); + audioburstmskdemodulator->setCPUReduce(ui->actionReduce_CPU->isChecked()); + audioburstmskdemodulatorsettings.zmqAudio =settingsdialog->zmqAudioInputEnabled; if(typeofdemodtouse==BURSTMSK)audioburstmskdemodulator->start(); //add todays date @@ -227,22 +234,6 @@ MainWindow::MainWindow(QWidget *parent) : settingsdialog->populatesettings(); acceptsettings(); - /*QString teststr="F58ADL0040/AKLCDYA.ADS.N705DN07EEE19454DAC7D010D21D0DEEEC44556208024029F0588C71D7884D000E13B90F00000F12C1A280001029305F1019F4"; - // //teststr="F61AQF0027#M1B/B6 AKLCDYA.ADS.VH-OEI14DC715BE394C80ED02D1D0DDBBBBBEEEEC80E8258D82D843333080E800F85"; - teststr="A92AXA42FD#M1B/B6 OAKODYA.ADS..N42FD0724FE94A9BECAFC4DF01F0D24FA4CAAAACAFC802D238E3CE38E4AFC800E24B0F540040F25899FC004101420DEB82858"; - teststr="F21AUA082/FUKJJYA.ADS.N772UA070DD5F32FBD894736B79D1602BC7B5928E04EA01600C97B8938806560171165E328E289C408AA0D0EEF9B2D8D897302AD11C88B282289C4000E7B50F780000F79F9A30000BB12"; - //teststr="F42AUA0828/FUKJJYA.ADS.N772UA07150C231FE549470E3D1D1600DF765128E01B401601F479E128E055C01603557D7128E0B5801601DF042928E0E6C0160073043908F8F2E01600B47DC8CC69078017188A7B1E12C57D48AB0D1556AB1E84094700DA160C0B1C7A8947000E76";//5"; - - teststr="J84ACI0017/OAKODYA.ADSB-183560301D095"; - ACARSItem tmpitem; - tmpitem.message=teststr; - tmpitem.downlink=true; - tmpitem.nonacars=false; - if(arincparser.parseDownlinkmessage(tmpitem)) - { - qDebug()<invalidatesettings(); audioburstoqpskdemodulator->invalidatesettings(); audioburstmskdemodulator->invalidatesettings(); - } lastdemodtype=demodtype; switch(demodtype) @@ -276,6 +266,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiooqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiooqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiooqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiooqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some burstoqpsk connections disconnect(audioburstoqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -290,6 +281,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstoqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstoqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstoqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstoqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //burstdemod demod2 disconnect(audioburstoqpskdemodulator->demod2, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -318,6 +310,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstmskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstmskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstmskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstmskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some msk connections connect(audiomskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -332,7 +325,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) connect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiomskdemodulator,SLOT(CenterFreqChangedSlot(double))); connect(audiomskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); connect(audiomskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); - + connect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)), audiomskdemodulator, SLOT(dataReceived(QByteArray,quint32)), Qt::UniqueConnection); break; case OQPSK: //opqsk @@ -349,7 +342,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiomskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiomskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiomskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); - + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiomskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some burstoqpsk connections disconnect(audioburstoqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -364,6 +357,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstoqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstoqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstoqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstoqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //burstdemod demod2 disconnect(audioburstoqpskdemodulator->demod2, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -392,6 +386,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstmskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstmskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstmskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstmskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some oqpsk connections connect(audiooqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -406,8 +401,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) connect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiooqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); connect(audiooqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); connect(audiooqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); - - + connect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)), audiooqpskdemodulator, SLOT(dataReceived(QByteArray,quint32)), Qt::UniqueConnection); break; case BURSTOQPSK: //burstopqsk @@ -425,6 +419,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiomskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiomskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiomskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiomskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some oqpsk connections disconnect(audiooqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -439,6 +434,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiooqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiooqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiooqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiooqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some burst msk connections disconnect(audioburstmskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -453,8 +449,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstmskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstmskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstmskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); - - + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstmskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some burstoqpsk connections connect(audioburstoqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -469,6 +464,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) connect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstoqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); connect(audioburstoqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); connect(audioburstoqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + connect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)), audioburstoqpskdemodulator, SLOT(dataReceived(QByteArray,quint32))); //burstdemod demod2 connect(audioburstoqpskdemodulator->demod2, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -501,6 +497,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiomskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiomskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiomskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiomskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some oqpsk connections disconnect(audiooqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -515,6 +512,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audiooqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audiooqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audiooqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audiooqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //some burstoqpsk connections disconnect(audioburstoqpskdemodulator, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -529,6 +527,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) disconnect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstoqpskdemodulator,SLOT(CenterFreqChangedSlot(double))); disconnect(audioburstoqpskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); disconnect(audioburstoqpskdemodulator, SIGNAL(SignalStatus(bool)),aerol,SLOT(SignalStatusSlot(bool))); + disconnect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)),audioburstoqpskdemodulator,SLOT(dataReceived(QByteArray,quint32))); //burstdemod demod2 disconnect(audioburstoqpskdemodulator->demod2, SIGNAL(Plottables(double,double,double)), this,SLOT(PlottablesSlot(double,double,double))); @@ -557,6 +556,7 @@ void MainWindow::selectdemodulatorconnections(DemodType demodtype) connect(ui->spectrumdisplay, SIGNAL(CenterFreqChanged(double)), audioburstmskdemodulator,SLOT(CenterFreqChangedSlot(double))); connect(audioburstmskdemodulator, SIGNAL(BitRateChanged(double,bool)), aerol,SLOT(setSettings(double,bool))); connect(audioburstmskdemodulator, SIGNAL(SignalStatus(bool)), aerol,SLOT(SignalStatusSlot(bool))); + connect(zmq_audio_receiver, SIGNAL(recAudio(const QByteArray&,quint32)), audioburstmskdemodulator, SLOT(dataReceived(QByteArray,quint32))); break; } @@ -658,9 +658,8 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) double bitrate_tmp=arg1.split(" ")[0].toDouble(); DemodType lasttypeofdemodtouse=typeofdemodtouse; - if(bitrate_tmp>1200){typeofdemodtouse=OQPSK;} - else {typeofdemodtouse=MSK; - } + if(bitrate_tmp>1200)typeofdemodtouse=OQPSK; + else typeofdemodtouse=MSK; if(arg.contains("burst")&&typeofdemodtouse==OQPSK)typeofdemodtouse=BURSTOQPSK; if(arg.contains("burst")&&typeofdemodtouse==MSK)typeofdemodtouse=BURSTMSK; @@ -670,7 +669,6 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulatorsettings.freq_center=audioburstoqpskdemodulator->getCurrentFreq(); audiomskdemodulatorsettings.freq_center=audioburstoqpskdemodulator->getCurrentFreq(); audioburstmskdemodulatorsettings.freq_center=audioburstoqpskdemodulator->getCurrentFreq(); - } if(lasttypeofdemodtouse==OQPSK) @@ -679,7 +677,6 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulatorsettings.freq_center=audiooqpskdemodulator->getCurrentFreq(); audiomskdemodulatorsettings.freq_center=audiooqpskdemodulator->getCurrentFreq(); audioburstmskdemodulatorsettings.freq_center=audiooqpskdemodulator->getCurrentFreq(); - } if(lasttypeofdemodtouse==MSK) @@ -688,7 +685,6 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulatorsettings.freq_center=audiomskdemodulator->getCurrentFreq(); audiomskdemodulatorsettings.freq_center=audiomskdemodulator->getCurrentFreq(); audioburstmskdemodulatorsettings.freq_center=audiomskdemodulator->getCurrentFreq(); - } if(lasttypeofdemodtouse==BURSTMSK) @@ -697,7 +693,6 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulatorsettings.freq_center=audioburstmskdemodulator->getCurrentFreq(); audiomskdemodulatorsettings.freq_center=audioburstmskdemodulator->getCurrentFreq(); audioburstmskdemodulatorsettings.freq_center=audioburstmskdemodulator->getCurrentFreq(); - } audiomskdemodulatorsettings.fb=bitrate_tmp; @@ -705,6 +700,10 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audioburstoqpskdemodulatorsettings.fb=bitrate_tmp; audioburstmskdemodulatorsettings.fb=bitrate_tmp; + audiooqpskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; + audiomskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; + audioburstoqpskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; + audioburstmskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; if(typeofdemodtouse==BURSTOQPSK) { @@ -712,7 +711,7 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulator->stop(); audioburstmskdemodulator->stop(); selectdemodulatorconnections(BURSTOQPSK); - audioburstoqpskdemodulatorsettings.Fs=48000; + int idx=ui->comboBoxlbw->findText(((QString)"%1 Hz").arg(audioburstoqpskdemodulatorsettings.fb*1.0)); if(idx>=0)audioburstoqpskdemodulatorsettings.lockingbw=ui->comboBoxlbw->itemText(idx).split(" ")[0].toDouble(); audioburstoqpskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; @@ -720,6 +719,7 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) else audioburstoqpskdemodulatorsettings.channel_stereo=false; audioburstoqpskdemodulator->setSettings(audioburstoqpskdemodulatorsettings); if(idx>=0)ui->comboBoxlbw->setCurrentIndex(idx); + audioburstoqpskdemodulator->start(); } @@ -743,6 +743,7 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiooqpskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; audiooqpskdemodulator->setSettings(audiooqpskdemodulatorsettings); if(idx>=0)ui->comboBoxlbw->setCurrentIndex(idx); + audiooqpskdemodulator->start(); } @@ -768,6 +769,7 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audiomskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; audiomskdemodulator->setSettings(audiomskdemodulatorsettings); if(idx>=0)ui->comboBoxlbw->setCurrentIndex(idx); + audiomskdemodulator->start(); } @@ -784,10 +786,10 @@ void MainWindow::on_comboBoxbps_currentIndexChanged(const QString &arg) audioburstmskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; audioburstmskdemodulator->setSettings(audioburstmskdemodulatorsettings); if(idx>=0)ui->comboBoxlbw->setCurrentIndex(idx); + audioburstmskdemodulator->start(); } - } void MainWindow::on_comboBoxlbw_currentIndexChanged(const QString &arg1) @@ -821,7 +823,6 @@ void MainWindow::on_comboBoxafc_currentIndexChanged(const QString &arg1) audiooqpskdemodulator->setAFC(true); audioburstoqpskdemodulator->setAFC(true); audioburstmskdemodulator->setAFC(true); - } else { @@ -829,7 +830,6 @@ void MainWindow::on_comboBoxafc_currentIndexChanged(const QString &arg1) audiooqpskdemodulator->setAFC(false); audioburstoqpskdemodulator->setAFC(false); audioburstmskdemodulator->setAFC(false); - } } @@ -868,7 +868,6 @@ void MainWindow::on_comboBoxdisplay_currentIndexChanged(const QString &arg1) audiooqpskdemodulator->setScatterPointType(OqpskDemodulator::SPT_constellation); audioburstoqpskdemodulator->setScatterPointType(BurstOqpskDemodulator::SPT_constellation); audioburstmskdemodulator->setScatterPointType(BurstMskDemodulator::SPT_constellation); - } if(arg1=="Symbol phase") { @@ -884,7 +883,6 @@ void MainWindow::on_comboBoxdisplay_currentIndexChanged(const QString &arg1) audiooqpskdemodulator->setScatterPointType(OqpskDemodulator::SPT_None); audioburstoqpskdemodulator->setScatterPointType(BurstOqpskDemodulator::SPT_None); audioburstmskdemodulator->setScatterPointType(BurstMskDemodulator::SPT_None); - } } @@ -896,7 +894,6 @@ void MainWindow::on_actionConnectToUDPPort_toggled(bool arg1) audioburstoqpskdemodulator->demod2->DisconnectSinkDevice(); audioburstmskdemodulator->DisconnectSinkDevice(); - aerol->DisconnectSinkDevice(); aerol2->DisconnectSinkDevice(); udpsocket->close(); @@ -991,13 +988,10 @@ void MainWindow::acceptsettings() } if(typeofdemodtouse==BURSTMSK)// we only use 48000 { - // audioburstmskdemodulatorsettings.Fs=48000; // audioburstmskdemodulator->setSettings(audioburstmskdemodulatorsettings); - } - if(typeofdemodtouse==OQPSK)//OQPSK uses 48000 all the time so not needed { //audiooqpskdemodulatorsettings.Fs=48000; @@ -1012,30 +1006,33 @@ void MainWindow::acceptsettings() //if soundcard device changed if(typeofdemodtouse==MSK) { - if(audiomskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice) + if(audiomskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice || audiomskdemodulatorsettings.zmqAudio != settingsdialog->zmqAudioInputEnabled ) { audiomskdemodulator->stop(); audiomskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; + audiomskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; audiomskdemodulator->setSettings(audiomskdemodulatorsettings); audiomskdemodulator->start(); } } if(typeofdemodtouse==OQPSK) { - if(audiooqpskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice) + if(audiooqpskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice || audiooqpskdemodulatorsettings.zmqAudio != settingsdialog->zmqAudioInputEnabled) { audiooqpskdemodulator->stop(); audiooqpskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; + audiooqpskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; audiooqpskdemodulator->setSettings(audiooqpskdemodulatorsettings); audiooqpskdemodulator->start(); } } if(typeofdemodtouse==BURSTOQPSK) { - if(audioburstoqpskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice) + if(audioburstoqpskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice || audioburstoqpskdemodulatorsettings.zmqAudio != settingsdialog->zmqAudioInputEnabled) { audioburstoqpskdemodulator->stop(); audioburstoqpskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; + audioburstoqpskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; audioburstoqpskdemodulator->setSettings(audioburstoqpskdemodulatorsettings); audioburstoqpskdemodulator->start(); } @@ -1043,10 +1040,11 @@ void MainWindow::acceptsettings() if(typeofdemodtouse==BURSTMSK) { - if(audioburstmskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice) + if(audioburstmskdemodulatorsettings.audio_device_in!=settingsdialog->audioinputdevice || audioburstmskdemodulatorsettings.zmqAudio != settingsdialog->zmqAudioInputEnabled) { audioburstmskdemodulator->stop(); audioburstmskdemodulatorsettings.audio_device_in=settingsdialog->audioinputdevice; + audioburstmskdemodulatorsettings.zmqAudio = settingsdialog->zmqAudioInputEnabled; audioburstmskdemodulator->setSettings(audioburstmskdemodulatorsettings); audioburstmskdemodulator->start(); } @@ -1087,6 +1085,26 @@ void MainWindow::acceptsettings() if(settingsdialog->loggingenable)compresseddiskwriter->setLogDir(settingsdialog->loggingdirectory); else compresseddiskwriter->setLogDir(""); + //zmq audio in from remote sdr + if(settingsdialog->zmqAudioInputEnabled)zmq_audio_receiver->Start(settingsdialog->zmqAudioInputAddress, settingsdialog->zmqAudioInputTopic); + else zmq_audio_receiver->Stop(); + + //local audio decode + if(settingsdialog->localAudioOutEnabled)connect(aerol,SIGNAL(Voicesignal(QByteArray)),ambe,SLOT(to_decode_slot(QByteArray)),Qt::UniqueConnection); + else disconnect(aerol,SIGNAL(Voicesignal(QByteArray)),ambe,SLOT(to_decode_slot(QByteArray))); + + //zmq compressed audio output + if(settingsdialog->zmqAudioOutEnabled) + { + zmq_audio_sender->Start(settingsdialog->zmqAudioOutBind,settingsdialog->zmqAudioOutTopic); + connect(aerol,SIGNAL(Voicesignal(QByteArray&, QString&)),zmq_audio_sender,SLOT(Voiceslot(QByteArray&, QString&)),Qt::UniqueConnection); + } + else + { + zmq_audio_sender->Stop(); + disconnect(aerol,SIGNAL(Voicesignal(QByteArray&, QString&)),zmq_audio_sender,SLOT(Voiceslot(QByteArray&, QString&))); + } + } void MainWindow::on_action_PlaneLog_triggered() @@ -1101,7 +1119,6 @@ void MainWindow::CChannelAssignmentSlot(CChannelAssignmentItem &item) if(item.receive_spotbeam)rx_beam=" Spot Beam "; message += "Receive Freq: " + QString::number(item.receive_freq) + rx_beam + "Transmit " + QString::number(item.transmit_freq); - switch(item.type) { case AEROTypeP::MessageType::C_channel_assignment_distress: @@ -1318,8 +1335,6 @@ void MainWindow::ERRorslot(QString &error) ui->inputwidget->appendHtml(""+error+""); } - - void MainWindow::on_tabWidget_currentChanged(int index) { Q_UNUSED(index); @@ -1349,11 +1364,8 @@ void MainWindow::on_actionSound_Out_toggled(bool mute) } } - void MainWindow::on_actionReduce_CPU_triggered(bool checked) { - audiooqpskdemodulator->setCPUReduce(checked); audiomskdemodulator->setCPUReduce(checked); - } diff --git a/JAERO/mainwindow.h b/JAERO/mainwindow.h index 9943e84..0e96b09 100644 --- a/JAERO/mainwindow.h +++ b/JAERO/mainwindow.h @@ -4,6 +4,7 @@ #include #include #include + #include "audiooqpskdemodulator.h" #include "audiomskdemodulator.h" #include "audioburstoqpskdemodulator.h" @@ -21,6 +22,9 @@ #include "audiooutdevice.h" #include "compressedaudiodiskwriter.h" +#include "zmq_audioreceiver.h" +#include "zmq_audiosender.h" + namespace Ui { class MainWindow; @@ -34,6 +38,8 @@ class MainWindow : public QMainWindow explicit MainWindow(QWidget *parent = 0); ~MainWindow(); +signals: + private: enum DemodType{NoDemodType,MSK,OQPSK,BURSTOQPSK,BURSTMSK}; Ui::MainWindow *ui; @@ -57,7 +63,6 @@ class MainWindow : public QMainWindow AudioBurstMskDemodulator *audioburstmskdemodulator; AudioBurstMskDemodulator::Settings audioburstmskdemodulatorsettings; - //bottom textedit output QList > udpsockets_bottom_textedit; @@ -88,6 +93,11 @@ class MainWindow : public QMainWindow ArincParse arincparser; QSound *beep; + + //ZeroMQ Audio Receiver + ZMQAudioReceiver *zmq_audio_receiver; + ZMQAudioSender *zmq_audio_sender; + protected: void closeEvent(QCloseEvent *event); @@ -118,6 +128,7 @@ private slots: void on_tabWidget_currentChanged(int index); void on_actionSound_Out_toggled(bool mute); void on_actionReduce_CPU_triggered(bool checked); + }; #endif // MAINWINDOW_H diff --git a/JAERO/mskdemodulator.cpp b/JAERO/mskdemodulator.cpp index 30de7cb..856dfea 100644 --- a/JAERO/mskdemodulator.cpp +++ b/JAERO/mskdemodulator.cpp @@ -134,6 +134,7 @@ void MskDemodulator::invalidatesettings() void MskDemodulator::setSettings(Settings _settings) { + last_applied_settings=_settings; if(_settings.Fs!=Fs)emit SampleRateChanged(_settings.Fs); Fs=_settings.Fs; lockingbw=_settings.lockingbw; @@ -368,14 +369,16 @@ qint64 MskDemodulator::writeData(const char *data, qint64 len) cpx_type cval= mixer2.WTCISValue()*(dval); cpx_type sig2 = cpx_type(matchedfilter_re->FIRUpdateAndProcess(cval.real()),matchedfilter_im->FIRUpdateAndProcess(cval.imag())); + double dabval = std::sqrt(sig2.real()*sig2.real() + sig2.imag()*sig2.imag()); + //Measure ebno - ebnomeasure->Update(std::abs(sig2)); + ebnomeasure->Update(dabval); //AGC - sig2*=agc->Update(std::abs(sig2)); + sig2*=agc->Update(dabval); //clipping - double abval=std::abs(sig2); + double abval=std::sqrt(sig2.real()*sig2.real() + sig2.imag()*sig2.imag()); if(abval>2.84)sig2=(2.84/abval)*sig2; cpx_type pt_d = delayedsmpl.update_dont_touch(sig2); @@ -522,6 +525,13 @@ void MskDemodulator::DCDstatSlot(bool _dcd) } - - - +void MskDemodulator::dataReceived(const QByteArray &audio,quint32 sampleRate) +{ + if(sampleRate!=Fs) + { + qDebug()<<"Sample rate different than expected. Trying to change demodulator sample rate"; + last_applied_settings.Fs=sampleRate; + setSettings(last_applied_settings); + } + writeData(audio, audio.length()); +} diff --git a/JAERO/mskdemodulator.h b/JAERO/mskdemodulator.h index 61bbf48..6e5aedc 100644 --- a/JAERO/mskdemodulator.h +++ b/JAERO/mskdemodulator.h @@ -30,6 +30,7 @@ class MskDemodulator : public QIODevice double Fs; int symbolspercycle; double signalthreshold; + bool zmqAudio; Settings() { coarsefreqest_fft_power=13;//2^coarsefreqest_fft_power @@ -39,6 +40,7 @@ class MskDemodulator : public QIODevice Fs=48000;//Hz symbolspercycle=16; signalthreshold=0.5; + zmqAudio=false; } }; explicit MskDemodulator(QObject *parent); @@ -140,6 +142,7 @@ class MskDemodulator : public QIODevice int coarseCounter; bool cpuReduce; + Settings last_applied_settings; signals: void ScatterPoints(const QVector &buffer); @@ -160,6 +163,8 @@ public slots: void FreqOffsetEstimateSlot(double freq_offset_est); void CenterFreqChangedSlot(double freq_center); void DCDstatSlot(bool dcd); + void dataReceived(const QByteArray &audio, quint32 sampleRate); + }; diff --git a/JAERO/oqpskdemodulator.cpp b/JAERO/oqpskdemodulator.cpp index e35d3d2..e8c4475 100644 --- a/JAERO/oqpskdemodulator.cpp +++ b/JAERO/oqpskdemodulator.cpp @@ -56,7 +56,7 @@ OqpskDemodulator::OqpskDemodulator(QObject *parent) connect(coarsefreqestimate, SIGNAL(FreqOffsetEstimate(double)),this,SLOT(FreqOffsetEstimateSlot(double))); RootRaisedCosine rrc; - rrc.design(1,55,48000,10500/2); + rrc.design(1,55,Fs,10500/2); fir_re=new FIR(rrc.Points.size()); fir_im=new FIR(rrc.Points.size()); for(int i=0;isetup_update(Fs,fb); @@ -452,10 +455,13 @@ qint64 OqpskDemodulator::writeData(const char *data, qint64 len) } //Measure ebno - ebnomeasure->Update(std::abs(sig2)); + + double dabval = std::sqrt(sig2.real()*sig2.real() + sig2.imag()*sig2.imag()); + + ebnomeasure->Update(dabval); //AGC - sig2*=agc->Update(std::abs(sig2)); + sig2*=agc->Update(dabval); //clipping double abval=std::abs(sig2); @@ -535,7 +541,7 @@ qint64 OqpskDemodulator::writeData(const char *data, qint64 len) if(!slowdown) { ASSERTCH(pointbuff,pointbuff_ptr); - pointbuff[pointbuff_ptr]=pt_qpsk; + pointbuff.replace(pointbuff_ptr,pt_qpsk); pointbuff_ptr++;pointbuff_ptr%=pointbuff.size(); //if(scatterpointtype==SPT_constellation&&(pointbuff_ptr%100==0))emit ScatterPoints(pointbuff); if(scatterpointtype==SPT_constellation&&sendscatterpoints){sendscatterpoints=false;emit ScatterPoints(pointbuff);} @@ -545,7 +551,7 @@ qint64 OqpskDemodulator::writeData(const char *data, qint64 len) { cpx_type st_phase_offset_pt=st_osc_ref.WTCISValue()*std::conj(st_osc.WTCISValue()); ASSERTCH(phasepointbuff,phasepointbuff_ptr); - phasepointbuff[phasepointbuff_ptr]=st_phase_offset_pt; + phasepointbuff.replace(phasepointbuff_ptr,st_phase_offset_pt); phasepointbuff_ptr++;phasepointbuff_ptr%=phasepointbuff.size(); //if(scatterpointtype==SPT_phaseoffsetest)emit ScatterPoints(phasepointbuff); if(scatterpointtype==SPT_phaseoffsetest&&sendscatterpoints){sendscatterpoints=false;emit ScatterPoints(phasepointbuff);} @@ -554,21 +560,8 @@ qint64 OqpskDemodulator::writeData(const char *data, qint64 len) //calc MSE of the points mse=msecalc->Update(pt_qpsk); - /* - //hard BPSK demod x2 - bool pt_qpsk_imag_demod=0; - bool pt_qpsk_real_demod=0; - if(pt_qpsk.imag()>0)pt_qpsk_imag_demod=1; - if(pt_qpsk.real()>0)pt_qpsk_real_demod=1; - - //if you want packed bits - bc.LoadSymbol(pt_qpsk_imag_demod); - bc.LoadSymbol(pt_qpsk_real_demod); - while(bc.DataAvailable) + if(mse +#include + +void ZMQAudioReceiver::Start(QString address, QString topic) +{ + //stop set prams and start thread + Stop(); + setParameters(address,topic); + future = QtConcurrent::run([=]() { + process(); + return; + }); + //wait till the thread is running so ZMQaudioStop functions correctly + for(int i=0;!running&&i<1000;i++)usleep(1000); + //if it fails after a second then arghhhhh, should not happen + if(!running) + { + qDebug()<<"Failed to start ZMQ receiving thread"; + } +} + +void ZMQAudioReceiver::Stop() +{ + running = false; + if(!future.isFinished())future.waitForFinished(); + emit finished(); +} + +void ZMQAudioReceiver::process() +{ + // allocate enough for 96Khz sampling with 1 buffer per second + int recsize = 192000; + context = zmq_ctx_new(); + subscriber = zmq_socket(context, ZMQ_SUB); + + zmqStatus = zmq_connect(subscriber, _address.toStdString().c_str()); + zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, _topic.toStdString().c_str(), 5); + + char buf [recsize]; + unsigned char rate[4]; + quint32 sampleRate; + int received; + + running = true; + + while(running) + { + + //blocking call alternative for topic, here we wait for the topic. + //I guess the sleep has to be less then the idle period between messages??? + while(((received = zmq_recv(subscriber, nullptr, 0, ZMQ_DONTWAIT))<0)&&running) + { + usleep(10000); + } + if(!running)break; + + //rate message is next + received = zmq_recv(subscriber, rate, 4, ZMQ_DONTWAIT); + if(!running)break; + memcpy(&sampleRate, rate, 4); + + //then audio data + received = zmq_recv(subscriber, buf, recsize, ZMQ_DONTWAIT); + if(!running)break; + if(received>=0) + { + QByteArray qdata(buf, received); + emit recAudio(qdata,sampleRate); + } + + } + + if(subscriber)zmq_close(subscriber); + if(context)zmq_ctx_destroy(context); + subscriber=nullptr; + context=nullptr; +} + +ZMQAudioReceiver::ZMQAudioReceiver(QObject *parent): + QObject(parent), + running(false), + context(nullptr), + subscriber(nullptr) +{ + +} + +ZMQAudioReceiver::~ZMQAudioReceiver() +{ + Stop(); +} + +void ZMQAudioReceiver::setParameters(QString address, QString topic) +{ + _address = address; + _topic = topic; +} + + diff --git a/JAERO/zmq_audioreceiver.h b/JAERO/zmq_audioreceiver.h new file mode 100644 index 0000000..ffa958c --- /dev/null +++ b/JAERO/zmq_audioreceiver.h @@ -0,0 +1,49 @@ +#ifndef ZMQ_AUDIORECEIVER_H +#define ZMQ_AUDIORECEIVER_H + +#include +#include +#include + +class ZMQAudioReceiver : public QObject +{ + Q_OBJECT + +public: + + explicit ZMQAudioReceiver(QObject *parent = 0); + ~ZMQAudioReceiver(); + +public slots: + + void Stop(); + void Start(QString address, QString topic); + +signals: + + void finished(); + +private: + + void setParameters(QString address, QString topic); + volatile bool running; + + void process(); + + void * volatile context; + void * volatile subscriber; + + int zmqStatus; + + QString _address; + QString _topic; + int _rate; + + QFuture future; + +signals: + void recAudio(const QByteArray & audio,quint32 sampleRate); + +}; + +#endif // AUDIORECEIVER_H diff --git a/JAERO/zmq_audiosender.cpp b/JAERO/zmq_audiosender.cpp new file mode 100644 index 0000000..c60c8bf --- /dev/null +++ b/JAERO/zmq_audiosender.cpp @@ -0,0 +1,51 @@ +#include "zmq_audiosender.h" +#include "zmq.h" +#include + +ZMQAudioSender::ZMQAudioSender(QObject *parent) : QObject(parent) +{ + zmqStatus = -1; + context = zmq_ctx_new(); + publisher = zmq_socket(context, ZMQ_PUB); + + int keepalive = 1; + int keepalivecnt = 10; + int keepaliveidle = 1; + int keepaliveintrv = 1; + + zmq_setsockopt(publisher, ZMQ_TCP_KEEPALIVE,(void*)&keepalive, sizeof(ZMQ_TCP_KEEPALIVE)); + zmq_setsockopt(publisher, ZMQ_TCP_KEEPALIVE_CNT,(void*)&keepalivecnt,sizeof(ZMQ_TCP_KEEPALIVE_CNT)); + zmq_setsockopt(publisher, ZMQ_TCP_KEEPALIVE_IDLE,(void*)&keepaliveidle,sizeof(ZMQ_TCP_KEEPALIVE_IDLE)); + zmq_setsockopt(publisher, ZMQ_TCP_KEEPALIVE_INTVL,(void*)&keepaliveintrv,sizeof(ZMQ_TCP_KEEPALIVE_INTVL)); +} + +void ZMQAudioSender::Start(QString &address, QString &topic) +{ + Stop(); + // bind socket + this->topic=topic; + connected_url=address.toUtf8().constData(); + zmqStatus=zmq_bind(publisher, connected_url.c_str() ); +} + +void ZMQAudioSender::Stop() +{ + if(zmqStatus == 0) + { + zmqStatus = zmq_disconnect(publisher, connected_url.c_str()); + } +} + +void ZMQAudioSender::Voiceslot(QByteArray &data, QString &hex) +{ + std::string topic_text = topic.toUtf8().constData(); + zmq_setsockopt(publisher, ZMQ_IDENTITY, topic_text.c_str(), topic_text.length()); + + if(data.length()!=0) + { + zmq_send(publisher, topic_text.c_str(), topic_text.length(), ZMQ_SNDMORE); + zmq_send(publisher, data.data(), data.length(), 0 ); + } + zmq_send(publisher, topic_text.c_str(), 5, ZMQ_SNDMORE); + zmq_send(publisher, hex.toStdString().c_str(), 6, 0 ); +} diff --git a/JAERO/zmq_audiosender.h b/JAERO/zmq_audiosender.h new file mode 100644 index 0000000..f95eea3 --- /dev/null +++ b/JAERO/zmq_audiosender.h @@ -0,0 +1,24 @@ +#ifndef ZMQ_AUDIOSENDER_H +#define ZMQ_AUDIOSENDER_H + +#include + +class ZMQAudioSender : public QObject +{ + Q_OBJECT +public: + explicit ZMQAudioSender(QObject *parent = 0); + void Start(QString &address,QString &topic); + void Stop(); +signals: +public slots: + void Voiceslot(QByteArray &data, QString &hex); +private: + void* context; + void* publisher; + int zmqStatus; + std::string connected_url; + QString topic; +}; + +#endif // ZMQ_AUDIOSENDER_H diff --git a/ci-linux-build.sh b/ci-linux-build.sh index c588658..43265c2 100755 --- a/ci-linux-build.sh +++ b/ci-linux-build.sh @@ -17,7 +17,7 @@ set -e if [[ ! $(sudo echo 0) ]]; then exit; fi #install dependancies and build tools -sudo apt-get install qt5-default cpputest build-essential qtmultimedia5-dev cmake libvorbis-dev libogg-dev libqt5multimedia5-plugins checkinstall libqcustomplot-dev libqt5svg5-dev -y +sudo apt-get install qt5-default cpputest build-essential qtmultimedia5-dev cmake libvorbis-dev libogg-dev libqt5multimedia5-plugins checkinstall libqcustomplot-dev libqt5svg5-dev libzmq3-dev -y #get script path SCRIPT=$(realpath $0) @@ -170,7 +170,7 @@ Package: ${PACKAGE_NAME} Source: ${PACKAGE_SOURCE} Section: base Priority: extra -Depends: qt5-default (>= 5.12), qtmultimedia5-dev, libvorbis-dev, libogg-dev, libqt5multimedia5-plugins, libqcustomplot-dev, libqt5svg5-dev +Depends: qt5-default (>= 5.12), qtmultimedia5-dev, libvorbis-dev, libogg-dev, libqt5multimedia5-plugins, libqcustomplot-dev, libqt5svg5-dev, libzmq3-dev Provides: ${PACKAGE_NAME} Maintainer: ${MAINTAINER} Version: ${PACKAGE_VERSION%_*} diff --git a/ci-windows-build.sh b/ci-windows-build.sh index 5229612..246f745 100755 --- a/ci-windows-build.sh +++ b/ci-windows-build.sh @@ -14,7 +14,7 @@ #fail on first error set -e -pacman -S --needed --noconfirm git mingw-w64-x86_64-toolchain autoconf libtool mingw-w64-x86_64-cpputest mingw-w64-x86_64-qt5 mingw-w64-x86_64-cmake mingw-w64-x86_64-libvorbis zip p7zip unzip +pacman -S --needed --noconfirm git mingw-w64-x86_64-toolchain autoconf libtool mingw-w64-x86_64-cpputest mingw-w64-x86_64-qt5 mingw-w64-x86_64-cmake mingw-w64-x86_64-libvorbis zip p7zip unzip mingw-w64-x86_64-zeromq #get script path SCRIPT=$(realpath $0) @@ -123,6 +123,8 @@ cp /mingw64/bin/libintl-8.dll $PWD cp /mingw64/bin/libpcre-1.dll $PWD cp /mingw64/bin/libbrotlicommon.dll $PWD cp /mingw64/bin/libiconv-2.dll $PWD +cp /mingw64/bin/libzmq.dll $PWD +cp /mingw64/bin/libsodium-23.dll $PWD #7za.exe not needed anymore #cp /usr/lib/p7zip/7za.exe $PWD #cp /usr/bin/msys-stdc++-6.dll $PWD