diff --git a/modems/m17/M17Modulator.h b/modems/m17/M17Modulator.h index 2947d0717..c55287aeb 100644 --- a/modems/m17/M17Modulator.h +++ b/modems/m17/M17Modulator.h @@ -111,7 +111,7 @@ public: return baseband; } - static std::array make_lsf(lsf_t& lsf, const std::string& src, const std::string& dest, int8_t can = 10, bool streamElsePacket = false) + static std::array make_lsf(lsf_t& lsf, const std::string& src, const std::string& dest, uint8_t can = 10, bool streamElsePacket = false) { lsf.fill(0); @@ -380,6 +380,7 @@ public: M17Modulator(const std::string& source, const std::string& dest = "") : source_(encode_callsign(source)), dest_(encode_callsign(dest)), + can_(10), rrc(makeFirFilter(rrc_taps)) { } @@ -398,9 +399,17 @@ public: dest_ = encode_callsign(callsign); } + /** + * Set the Channel Access Number (0..15) + */ + void can(uint8_t can) { + can_ = can & 0xF; + } + private: LinkSetupFrame::encoded_call_t source_; LinkSetupFrame::encoded_call_t dest_; + uint8_t can_; BaseFirFilter<150> rrc; static const std::array rrc_taps; CRC16<0x5935, 0xFFFF> crc_; diff --git a/plugins/channeltx/modm17/m17modgui.cpp b/plugins/channeltx/modm17/m17modgui.cpp index ab40f82e8..ea1289102 100644 --- a/plugins/channeltx/modm17/m17modgui.cpp +++ b/plugins/channeltx/modm17/m17modgui.cpp @@ -767,6 +767,7 @@ void M17ModGUI::makeUIConnections() QObject::connect(ui->smsText, &CustomTextEdit::editingFinished, this, &M17ModGUI::on_smsText_editingFinished); QObject::connect(ui->source, &QLineEdit::editingFinished, this, &M17ModGUI::on_source_editingFinished); QObject::connect(ui->destination, &QLineEdit::editingFinished, this, &M17ModGUI::on_destination_editingFinished); + QObject::connect(ui->can, QOverload::of(&QSpinBox::valueChanged), this, &M17ModGUI::on_can_valueChanged); } void M17ModGUI::updateAbsoluteCenterFrequency() diff --git a/plugins/channeltx/modm17/m17modgui.ui b/plugins/channeltx/modm17/m17modgui.ui index d5e9d1951..aaff57bf9 100644 --- a/plugins/channeltx/modm17/m17modgui.ui +++ b/plugins/channeltx/modm17/m17modgui.ui @@ -1314,7 +1314,7 @@ - 255 + 15 10 diff --git a/plugins/channeltx/modm17/m17modprocessor.cpp b/plugins/channeltx/modm17/m17modprocessor.cpp index 8820a23cb..a72ac627f 100644 --- a/plugins/channeltx/modm17/m17modprocessor.cpp +++ b/plugins/channeltx/modm17/m17modprocessor.cpp @@ -22,7 +22,6 @@ #include "m17modprocessor.h" MESSAGE_CLASS_DEFINITION(M17ModProcessor::MsgSendSMS, Message) -MESSAGE_CLASS_DEFINITION(M17ModProcessor::MsgSendAudio, Message) MESSAGE_CLASS_DEFINITION(M17ModProcessor::MsgSendAudioFrame, Message) MESSAGE_CLASS_DEFINITION(M17ModProcessor::MsgStartAudio, Message) MESSAGE_CLASS_DEFINITION(M17ModProcessor::MsgStopAudio, Message) @@ -54,17 +53,10 @@ bool M17ModProcessor::handleMessage(const Message& cmd) QByteArray packetBytes = notif.getSMSText().toUtf8(); packetBytes.prepend(0x05); // SMS standard type packetBytes.truncate(798); // Maximum packet size is 798 payload + 2 bytes CRC = 800 bytes (32*25) - processPacket(notif.getSourceCall(), notif.getDestCall(), packetBytes); + processPacket(notif.getSourceCall(), notif.getDestCall(), notif.getCAN(), packetBytes); // test(notif.getSourceCall(), notif.getDestCall()); return true; } - else if (MsgSendAudio::match(cmd)) - { - MsgSendAudio& notif = (MsgSendAudio&) cmd; - // qDebug("M17ModProcessor::handleMessage: MsgSendAudio: %lu samples", notif.getAudioBuffer().size()); - processAudio(notif.getAudioBuffer()); - return true; - } else if (MsgSendAudioFrame::match(cmd)) { MsgSendAudioFrame& notif = (MsgSendAudioFrame&) cmd; @@ -77,7 +69,7 @@ bool M17ModProcessor::handleMessage(const Message& cmd) MsgStartAudio& notif = (MsgStartAudio&) cmd; qDebug("M17ModProcessor::handleMessage: MsgStartAudio: %s to %s", qPrintable(notif.getSourceCall()), qPrintable(notif.getDestCall())); - audioStart(notif.getSourceCall(), notif.getDestCall()); + audioStart(notif.getSourceCall(), notif.getDestCall(), notif.getCAN()); return true; } else if (MsgStopAudio::match(cmd)) @@ -113,7 +105,7 @@ void M17ModProcessor::test(const QString& sourceCall, const QString& destCall) } } -void M17ModProcessor::processPacket(const QString& sourceCall, const QString& destCall, const QByteArray& packetBytes) +void M17ModProcessor::processPacket(const QString& sourceCall, const QString& destCall, uint8_t can, const QByteArray& packetBytes) { qDebug("M17ModProcessor::processPacket: %s to %s: %s", qPrintable(sourceCall), qPrintable(destCall), qPrintable(packetBytes)); m_m17Modulator.source(sourceCall.toStdString()); @@ -123,7 +115,7 @@ void M17ModProcessor::processPacket(const QString& sourceCall, const QString& de // LSF std::array lsf; - std::array lsf_frame = mobilinkd::M17Modulator::make_lsf(lsf, sourceCall.toStdString(), destCall.toStdString()); + std::array lsf_frame = mobilinkd::M17Modulator::make_lsf(lsf, sourceCall.toStdString(), destCall.toStdString(), can); output_baseband(mobilinkd::M17Modulator::LSF_SYNC_WORD, lsf_frame); // Packets @@ -150,18 +142,19 @@ void M17ModProcessor::processPacket(const QString& sourceCall, const QString& de send_eot(); // EOT } -void M17ModProcessor::audioStart(const QString& sourceCall, const QString& destCall) +void M17ModProcessor::audioStart(const QString& sourceCall, const QString& destCall, uint8_t can) { qDebug("M17ModProcessor::audioStart"); m_m17Modulator.source(sourceCall.toStdString()); m_m17Modulator.dest(destCall.toStdString()); + m_m17Modulator.can(can); m_audioFrameNumber = 0; send_preamble(); // preamble // LSF std::array lsf; - std::array lsf_frame = mobilinkd::M17Modulator::make_lsf(lsf, sourceCall.toStdString(), destCall.toStdString()); + std::array lsf_frame = mobilinkd::M17Modulator::make_lsf(lsf, sourceCall.toStdString(), destCall.toStdString(), can, true); output_baseband(mobilinkd::M17Modulator::LSF_SYNC_WORD, lsf_frame); // Prepare LICH @@ -197,46 +190,6 @@ void M17ModProcessor::send_preamble() m_basebandFifo.write(preamble_baseband.data(), 1920); } -void M17ModProcessor::processAudio(const std::vector& audioBuffer) -{ - int audioBufferRemainder = audioBuffer.size(); - std::vector::const_iterator audioBufferIt = audioBuffer.begin(); - int audioFrameRemainder = m_audioFrame.size() - m_audioFrameIndex; - - if (audioBufferRemainder < audioFrameRemainder) { - qDebug("M17ModProcessor::processAudio: too few samples: %d/%d", audioBufferRemainder, audioFrameRemainder); - } - - while (audioBufferRemainder >= (int) m_audioFrame.size()) - { - m_audioFrame.fill(0); - - std::copy( - audioBufferIt, - audioBufferIt + audioFrameRemainder, - m_audioFrame.begin() + m_audioFrameIndex); - - if (m_basebandFifo.getFill() < m_basebandFifoHigh) { - processAudioFrame(); - } - - if (m_basebandFifo.getFill() < m_basebandFifoLow) - { - qDebug("M17ModProcessor::processAudio: repeat frame: %d", m_basebandFifo.getFill()); - // m_audioFrame.fill(0); - processAudioFrame(); - } - - audioBufferRemainder -= audioFrameRemainder; - audioBufferIt += audioFrameRemainder; - m_audioFrameIndex = 0; - audioFrameRemainder = m_audioFrame.size(); - } - - std::copy(audioBufferIt, audioBuffer.end(), m_audioFrame.begin()); - m_audioFrameIndex = audioBufferRemainder; -} - void M17ModProcessor::processAudioFrame() { std::array audioPayload = encodeAudio(m_audioFrame); @@ -265,7 +218,6 @@ std::array M17ModProcessor::encodeAudio(std::array& std::array audioFrame8k; m_decimator.decimate(audioFrame.data(), audioFrame8k.data(), 320); std::array result; - // result.fill(0); // test codec2_encode(m_codec2, &result[0], const_cast(&audioFrame8k[0])); codec2_encode(m_codec2, &result[8], const_cast(&audioFrame8k[160])); return result; diff --git a/plugins/channeltx/modm17/m17modprocessor.h b/plugins/channeltx/modm17/m17modprocessor.h index 3c2e23cc3..528380e83 100644 --- a/plugins/channeltx/modm17/m17modprocessor.h +++ b/plugins/channeltx/modm17/m17modprocessor.h @@ -38,49 +38,28 @@ public: public: const QString& getSourceCall() const { return m_sourceCall; } const QString& getDestCall() const { return m_destCall; } + uint8_t getCAN() const { return m_can; } const QString& getSMSText() const { return m_smsText; } - static MsgSendSMS* create(const QString& sourceCall, const QString& destCall, const QString& smsText) { - return new MsgSendSMS(sourceCall, destCall, smsText); + static MsgSendSMS* create(const QString& sourceCall, const QString& destCall, uint8_t can, const QString& smsText) { + return new MsgSendSMS(sourceCall, destCall, can, smsText); } private: QString m_sourceCall; QString m_destCall; + uint8_t m_can; QString m_smsText; - MsgSendSMS(const QString& sourceCall, const QString& destCall, const QString& smsText) : + MsgSendSMS(const QString& sourceCall, const QString& destCall, uint8_t can, const QString& smsText) : Message(), m_sourceCall(sourceCall), m_destCall(destCall), + m_can(can), m_smsText(smsText) { } }; - class MsgSendAudio : public Message { - MESSAGE_CLASS_DECLARATION - - public: - const QString& getSourceCall() const { return m_sourceCall; } - const QString& getDestCall() const { return m_destCall; } - std::vector& getAudioBuffer() { return m_audioBuffer; } - - static MsgSendAudio* create(const QString& sourceCall, const QString& destCall) { - return new MsgSendAudio(sourceCall, destCall); - } - - private: - QString m_sourceCall; - QString m_destCall; - std::vector m_audioBuffer; - - MsgSendAudio(const QString& sourceCall, const QString& destCall) : - Message(), - m_sourceCall(sourceCall), - m_destCall(destCall) - { } - }; - class MsgSendAudioFrame : public Message { MESSAGE_CLASS_DECLARATION @@ -111,19 +90,22 @@ public: public: const QString& getSourceCall() const { return m_sourceCall; } const QString& getDestCall() const { return m_destCall; } + uint8_t getCAN() const { return m_can; } - static MsgStartAudio* create(const QString& sourceCall, const QString& destCall) { - return new MsgStartAudio(sourceCall, destCall); + static MsgStartAudio* create(const QString& sourceCall, const QString& destCall, uint8_t can) { + return new MsgStartAudio(sourceCall, destCall, can); } private: QString m_sourceCall; QString m_destCall; + uint8_t m_can; - MsgStartAudio(const QString& sourceCall, const QString& destCall) : + MsgStartAudio(const QString& sourceCall, const QString& destCall, uint8_t can) : Message(), m_sourceCall(sourceCall), - m_destCall(destCall) + m_destCall(destCall), + m_can(can) { } }; @@ -163,10 +145,9 @@ private: struct CODEC2 *m_codec2; bool handleMessage(const Message& cmd); - void processPacket(const QString& sourceCall, const QString& destCall, const QByteArray& packetBytes); - void audioStart(const QString& sourceCall, const QString& destCall); + void processPacket(const QString& sourceCall, const QString& destCall, uint8_t can, const QByteArray& packetBytes); + void audioStart(const QString& sourceCall, const QString& destCall, uint8_t can); void audioStop(); - void processAudio(const std::vector& audioBuffer); void processAudioFrame(); std::array encodeAudio(std::array& audioFrame); void test(const QString& sourceCall, const QString& destCall); diff --git a/plugins/channeltx/modm17/m17modsource.cpp b/plugins/channeltx/modm17/m17modsource.cpp index 65ec9928a..c985997d2 100644 --- a/plugins/channeltx/modm17/m17modsource.cpp +++ b/plugins/channeltx/modm17/m17modsource.cpp @@ -231,7 +231,7 @@ void M17ModSource::pullAF(Real& sample, bool& carrier) { if (m_settings.m_audioType == M17ModSettings::AudioFile) { - // sox f4exb_call.wav --encoding float --endian little f4exb_call.raw + // sox f4exb_call.wav --encoding float --endian little --rate 48k f4exb_call.raw // ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw if (m_ifstream && m_ifstream->is_open()) { @@ -287,7 +287,10 @@ void M17ModSource::pullM17(Real& sample, bool& carrier) { if (!m_m17PullAudio) { - M17ModProcessor::MsgStartAudio *msg = M17ModProcessor::MsgStartAudio::create(m_settings.m_sourceCall, m_settings.m_destCall); + M17ModProcessor::MsgStartAudio *msg = M17ModProcessor::MsgStartAudio::create( + m_settings.m_sourceCall, + m_settings.m_destCall, + m_settings.m_can); m_processor->getInputMessageQueue()->push(msg); m_m17PullAudio = true; } @@ -569,6 +572,7 @@ void M17ModSource::sendPacket() M17ModProcessor::MsgSendSMS *msg = M17ModProcessor::MsgSendSMS::create( m_settings.m_sourceCall, m_settings.m_destCall, + m_settings.m_can, m_settings.m_smsText ); m_processor->getInputMessageQueue()->push(msg);