mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-20 22:45:44 +08:00
Merge branch 'FIR' into IAX
This commit is contained in:
78
FIR.cpp
Normal file
78
FIR.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2024 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "FIR.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cassert>
|
||||
|
||||
CFIR::CFIR(const float* taps, unsigned int count) :
|
||||
m_line(NULL),
|
||||
m_taps(NULL),
|
||||
m_count(count),
|
||||
m_index(0U)
|
||||
{
|
||||
assert(taps != NULL);
|
||||
assert(count > 0U);
|
||||
|
||||
m_line = new float[count];
|
||||
m_taps = new float[count];
|
||||
|
||||
for (unsigned int i = 0U; i < count; i++) {
|
||||
m_line[i] = 0.0F;
|
||||
m_taps[i] = taps[i];
|
||||
}
|
||||
}
|
||||
|
||||
CFIR::~CFIR()
|
||||
{
|
||||
delete[] m_line;
|
||||
delete[] m_taps;
|
||||
}
|
||||
|
||||
float CFIR::filter(float sample)
|
||||
{
|
||||
m_line[m_index] = sample;
|
||||
|
||||
m_index++;
|
||||
if (m_index >= m_count)
|
||||
m_index = 0U;
|
||||
|
||||
float out = 0.0F;
|
||||
|
||||
unsigned int index = m_index;
|
||||
|
||||
for (unsigned int i = 0U; i < m_count; i++) {
|
||||
if (index > 0U)
|
||||
index--;
|
||||
else
|
||||
index = m_count - 1U;
|
||||
|
||||
out += m_taps[i] * m_line[index];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void CFIR::reset()
|
||||
{
|
||||
for (unsigned int i = 0U; i < m_count; i++)
|
||||
m_line[i] = 0.0F;
|
||||
|
||||
m_index = 0U;
|
||||
}
|
||||
39
FIR.h
Normal file
39
FIR.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2024 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(FIR_H)
|
||||
#define FIR_H
|
||||
|
||||
class CFIR
|
||||
{
|
||||
public:
|
||||
CFIR(const float* taps, unsigned int count);
|
||||
~CFIR();
|
||||
|
||||
float filter(float sample);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
float* m_line;
|
||||
float* m_taps;
|
||||
unsigned int m_count;
|
||||
unsigned int m_index;
|
||||
};
|
||||
|
||||
#endif
|
||||
168
FMControl.cpp
168
FMControl.cpp
@@ -30,10 +30,55 @@
|
||||
|
||||
const float DEEMPHASIS_GAIN_DB = 8.0F; // Audio gain adjustment
|
||||
const float PREEMPHASIS_GAIN_DB = 0.0F; // Audio gain adjustment
|
||||
const float FILTER_GAIN_DB = 2.0F; // Audio gain adjustment
|
||||
const unsigned int FM_MASK = 0x00000FFFU;
|
||||
|
||||
CFMControl::CFMControl(IFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn) :
|
||||
// Created using http://t-filter.engineerjs.com/
|
||||
const float FILTER_TAPS[] = {
|
||||
-0.05171164345032154F, 0.004577697825204152F, 0.0841254955090718F, 0.021290266836279378F, -0.004089760781267529F,
|
||||
0.017543929045823792F, -0.019757885035823444F, -0.007257327157430058F, -0.004449379743389856F, -0.02385756312026885F,
|
||||
0.0008185571872412343F, -0.013864145248825219F, -0.011210498318183482F, 0.005254565026658612F, -0.015043483504571332F,
|
||||
0.005461884596609861F, 0.002026322985797473F, -0.007542135237135551F, 0.015720810214077726F, -0.004651704877827266F,
|
||||
0.005558418419098179F, 0.013941762626730268F, -0.007509473824811953F, 0.016618272581132985F, 0.002487274459992476F,
|
||||
-0.0024802940122075103F, 0.017683063350944713F, -0.009994442394814056F, 0.007156447064599394F, 0.006433822485904772F
|
||||
-0.014292696730698431F, 0.013319129319180239F, -0.010408978940031273F, -0.007266470155557534F, 0.009230635462251885F,
|
||||
-0.021463578074814135F, 0.005194836976513505F, -0.004126873023205119F, -0.01808260377380932F, 0.01304137129976236F,
|
||||
-0.017532323849990875F, -0.001929317250481216F, 0.009395238582798674F, -0.01975948679774396F, 0.01622855958724977F,
|
||||
-0.0029621037585558234F, -0.006899065995755296F, 0.02321184132395859F, -0.013467585741796682F, 0.01371204158005827F,
|
||||
0.013692208003629535F, -0.012367114737680571F, 0.02722969001859293F, -0.005345784554487899F, 0.0010074007729973767F,
|
||||
0.022305163683623532F, -0.019636621576653458F, 0.016349411295640864F, 0.0003626724003974509F, -0.018539298657843845F,
|
||||
0.01994785867615676F, -0.024001641760916962F, -0.0034795731393629766F, 0.0060060611058407164F, -0.033081075064776075F,
|
||||
0.012754552578116456F, -0.01694452885708811F, -0.019221979726946815F, 0.016490911013530663F, -0.03092454436058619F,
|
||||
0.00861201477103357F, 0.004613884756593608F, -0.021987826895264795F, 0.030752871497932738F, -0.011775928674227762F,
|
||||
0.007473527853524001F, 0.03126561745903647F, -0.016067027177553667F, 0.0378218068192532F, 0.010312992900560435F,
|
||||
-0.0006238863579307288F, 0.04477891903198119F, -0.015623491538694835F, 0.02384438222815608F, 0.01750864066332353F,
|
||||
-0.026325530246751806F, 0.03302218423753518F, -0.03126149618245644F, -0.014849557775866738F, 0.005783253669755862F,
|
||||
-0.07047543753434074F, 0.004291583771423271F, -0.05850933604118403F, -0.06807719431962597F, 0.00009772317389628164F,
|
||||
-0.13523267568572162F, 0.0004875192337944561F, -0.07994164839657204F, -0.18719066454627675F, 0.5305904386356379F,
|
||||
0.5305904386356379F, -0.18719066454627675F, -0.07994164839657204F, 0.0004875192337944561F, -0.13523267568572162F,
|
||||
0.00009772317389628164F, -0.06807719431962597F, -0.05850933604118403F, 0.004291583771423271F, -0.07047543753434074F,
|
||||
0.005783253669755862F, -0.014849557775866738F, -0.03126149618245644F, 0.03302218423753518F, -0.026325530246751806F,
|
||||
0.01750864066332353F, 0.02384438222815608F, -0.015623491538694835F, 0.04477891903198119F, -0.0006238863579307288F,
|
||||
0.010312992900560435F, 0.0378218068192532F, -0.016067027177553667F, 0.03126561745903647F, 0.007473527853524001F,
|
||||
-0.011775928674227762F, 0.030752871497932738F, -0.021987826895264795F, 0.004613884756593608F, 0.00861201477103357F,
|
||||
-0.03092454436058619F, 0.016490911013530663F, -0.019221979726946815F, -0.01694452885708811F, 0.012754552578116456F,
|
||||
-0.033081075064776075F, 0.0060060611058407164F, -0.0034795731393629766F, -0.024001641760916962F, 0.01994785867615676F,
|
||||
-0.018539298657843845F, 0.0003626724003974509F, 0.016349411295640864F, -0.019636621576653458F, 0.022305163683623532F,
|
||||
0.0010074007729973767F, -0.005345784554487899F, 0.02722969001859293F, -0.012367114737680571F, 0.013692208003629535F,
|
||||
0.01371204158005827F, -0.013467585741796682F, 0.02321184132395859F, -0.006899065995755296F, -0.0029621037585558234F,
|
||||
0.01622855958724977F, -0.01975948679774396F, 0.009395238582798674F, -0.001929317250481216F, -0.017532323849990875F,
|
||||
0.01304137129976236F, -0.01808260377380932F, -0.004126873023205119F, 0.005194836976513505F, -0.021463578074814135F,
|
||||
0.009230635462251885F, -0.007266470155557534F, -0.010408978940031273F, 0.013319129319180239F, -0.014292696730698431F,
|
||||
0.006433822485904772F, 0.007156447064599394F, -0.009994442394814056F, 0.017683063350944713F, -0.0024802940122075103F,
|
||||
0.002487274459992476F, 0.016618272581132985F, -0.007509473824811953F, 0.013941762626730268F, 0.005558418419098179F,
|
||||
-0.004651704877827266F, 0.015720810214077726F, -0.007542135237135551F, 0.002026322985797473F, 0.005461884596609861F,
|
||||
-0.015043483504571332F, 0.005254565026658612F, -0.011210498318183482F, -0.013864145248825219F, 0.0008185571872412343F,
|
||||
-0.02385756312026885F, -0.004449379743389856F, -0.007257327157430058F, -0.019757885035823444F, 0.017543929045823792F,
|
||||
-0.004089760781267529F, 0.021290266836279378F, 0.0841254955090718F, 0.004577697825204152F, -0.05171164345032154F
|
||||
};
|
||||
|
||||
const unsigned int FILTER_TAPS_COUNT = 200U;
|
||||
|
||||
CFMControl::CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn) :
|
||||
m_network(network),
|
||||
m_txAudioGain(txAudioGain),
|
||||
m_rxAudioGain(rxAudioGain),
|
||||
@@ -42,95 +87,72 @@ m_deEmphasisOn(deEmphasisOn),
|
||||
m_enabled(false),
|
||||
m_begin(true),
|
||||
m_incomingRFAudio(1600U, "Incoming RF FM Audio"),
|
||||
m_preEmphasis(NULL),
|
||||
m_deEmphasis(NULL),
|
||||
m_filterStage1(NULL),
|
||||
m_filterStage2(NULL),
|
||||
m_filterStage3(NULL)
|
||||
m_preEmphasis(8.315375384336983F, -7.03334621603483F, 0.0F, 1.0F, 0.282029168302153F, 0.0F, PREEMPHASIS_GAIN_DB),
|
||||
m_deEmphasis(0.07708787090460224F, 0.07708787090460224F, 0.0F, 1.0F, -0.8458242581907955F, 0.0F, DEEMPHASIS_GAIN_DB),
|
||||
m_filter(FILTER_TAPS, FILTER_TAPS_COUNT)
|
||||
{
|
||||
assert(txAudioGain > 0.0F);
|
||||
assert(rxAudioGain > 0.0F);
|
||||
|
||||
m_preEmphasis = new CIIRDirectForm1Filter(8.315375384336983F, -7.03334621603483F,0.0F,1.0F, 0.282029168302153F,0.0F, PREEMPHASIS_GAIN_DB);
|
||||
m_deEmphasis = new CIIRDirectForm1Filter(0.07708787090460224F, 0.07708787090460224F,0.0F, 1.0F, -0.8458242581907955F,0.0F, DEEMPHASIS_GAIN_DB);
|
||||
|
||||
// Chebyshev type 1 0.2dB cheby type 1 3rd order 300-2700Hz fs=8000
|
||||
m_filterStage1 = new CIIRDirectForm1Filter(0.29495028f, 0.0f, -0.29495028f, 1.0f, -0.61384624f, -0.057158668f, FILTER_GAIN_DB);
|
||||
m_filterStage2 = new CIIRDirectForm1Filter(1.0f, 2.0f, 1.0f, 1.0f, 0.9946123f, 0.6050482f, FILTER_GAIN_DB);
|
||||
m_filterStage3 = new CIIRDirectForm1Filter(1.0f, -2.0f, 1.0f, 1.0f, -1.8414584f, 0.8804949f, FILTER_GAIN_DB);
|
||||
assert(txAudioGain > 0.0F);
|
||||
assert(rxAudioGain > 0.0F);
|
||||
}
|
||||
|
||||
CFMControl::~CFMControl()
|
||||
{
|
||||
delete m_preEmphasis;
|
||||
delete m_deEmphasis;
|
||||
|
||||
delete m_filterStage1;
|
||||
delete m_filterStage2;
|
||||
delete m_filterStage3;
|
||||
}
|
||||
|
||||
bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
if (m_network == NULL)
|
||||
return true;
|
||||
if (m_network == NULL)
|
||||
return true;
|
||||
|
||||
if (data[0U] == TAG_HEADER)
|
||||
return true;
|
||||
if (data[0U] == TAG_HEADER)
|
||||
return true;
|
||||
|
||||
if (data[0U] == TAG_EOT) {
|
||||
m_begin = true;
|
||||
return m_network->writeEnd();
|
||||
}
|
||||
if (data[0U] == TAG_EOT)
|
||||
return m_network->writeEnd();
|
||||
|
||||
if (data[0U] != TAG_DATA)
|
||||
return false;
|
||||
if (data[0U] != TAG_DATA)
|
||||
return false;
|
||||
|
||||
if (m_begin) {
|
||||
m_begin = false;
|
||||
m_network->writeStart();
|
||||
}
|
||||
m_incomingRFAudio.addData(data + 1U, length - 1U);
|
||||
unsigned int bufferLength = m_incomingRFAudio.dataSize();
|
||||
if (bufferLength > 240U) // 160 samples 12-bit
|
||||
bufferLength = 240U; // 160 samples 12-bit
|
||||
|
||||
m_incomingRFAudio.addData(data + 1U, length - 1U);
|
||||
unsigned int bufferLength = m_incomingRFAudio.dataSize();
|
||||
if (bufferLength > 240U) // 160 samples 12-bit
|
||||
bufferLength = 240U; // 160 samples 12-bit
|
||||
if (bufferLength >= 3U) {
|
||||
bufferLength = bufferLength - bufferLength % 3U; // Round down to nearest multiple of 3
|
||||
unsigned char bufferData[240U]; // 160 samples 12-bit
|
||||
m_incomingRFAudio.getData(bufferData, bufferLength);
|
||||
|
||||
if (bufferLength >= 3U) {
|
||||
bufferLength = bufferLength - bufferLength % 3U; // Round down to nearest multiple of 3
|
||||
unsigned char bufferData[240U]; // 160 samples 12-bit
|
||||
m_incomingRFAudio.getData(bufferData, bufferLength);
|
||||
unsigned int pack = 0U;
|
||||
unsigned char* packPointer = (unsigned char*)&pack;
|
||||
float out[160U]; // 160 samples 12-bit
|
||||
unsigned int nOut = 0U;
|
||||
short unpackedSamples[2U];
|
||||
|
||||
unsigned int pack = 0U;
|
||||
unsigned char* packPointer = (unsigned char*)&pack;
|
||||
float out[160U]; // 160 samples 12-bit
|
||||
unsigned int nOut = 0U;
|
||||
short unpackedSamples[2U];
|
||||
for (unsigned int i = 0U; i < bufferLength; i += 3U) {
|
||||
// Extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed
|
||||
packPointer[0U] = bufferData[i + 0U];
|
||||
packPointer[1U] = bufferData[i + 1U];
|
||||
packPointer[2U] = bufferData[i + 2U];
|
||||
|
||||
for (unsigned int i = 0U; i < bufferLength; i += 3U) {
|
||||
// Extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed
|
||||
packPointer[0U] = bufferData[i + 0U];
|
||||
packPointer[1U] = bufferData[i + 1U];
|
||||
packPointer[2U] = bufferData[i + 2U];
|
||||
unpackedSamples[1U] = short(int(pack & FM_MASK) - 2048);
|
||||
unpackedSamples[0U] = short(int(pack >> 12 & FM_MASK) - 2048);
|
||||
|
||||
unpackedSamples[1U] = short(int(pack & FM_MASK) - 2048);
|
||||
unpackedSamples[0U] = short(int(pack >> 12 & FM_MASK) - 2048);
|
||||
// Process unpacked sample pair
|
||||
for (unsigned char j = 0U; j < 2U; j++) {
|
||||
// Convert to float (-1.0 to +1.0)
|
||||
float sampleFloat = (float(unpackedSamples[j]) * m_rxAudioGain) / 2048.0F;
|
||||
|
||||
// Process unpacked sample pair
|
||||
for (unsigned char j = 0U; j < 2U; j++) {
|
||||
// Convert to float (-1.0 to +1.0)
|
||||
float sampleFloat = (float(unpackedSamples[j]) * m_rxAudioGain) / 2048.0F;
|
||||
// De-emphasise and remove CTCSS
|
||||
if (m_deEmphasisOn)
|
||||
sampleFloat = m_deEmphasis.filter(sampleFloat);
|
||||
|
||||
// De-emphasise and remove CTCSS
|
||||
if (m_deEmphasisOn)
|
||||
sampleFloat = m_deEmphasis->filter(sampleFloat);
|
||||
|
||||
out[nOut++] = m_filterStage3->filter(m_filterStage2->filter(m_filterStage1->filter(sampleFloat)));
|
||||
}
|
||||
}
|
||||
out[nOut++] = m_filter.filter(sampleFloat);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DUMP_RF_AUDIO)
|
||||
FILE* audiofile = ::fopen("./audiodump.bin", "ab");
|
||||
@@ -168,9 +190,9 @@ unsigned int CFMControl::readModem(unsigned char* data, unsigned int space)
|
||||
for (unsigned int i = 0; i < length; i++) {
|
||||
float sampleFloat = netData[i] * m_txAudioGain;
|
||||
|
||||
// Pre-emphasis
|
||||
if (m_preEmphasisOn)
|
||||
sampleFloat = m_preEmphasis->filter(sampleFloat);
|
||||
// Pre-emphasis
|
||||
if (m_preEmphasisOn)
|
||||
sampleFloat = m_preEmphasis.filter(sampleFloat);
|
||||
|
||||
// Convert float to 12-bit samples (0 to 4095)
|
||||
unsigned int sample12bit = (unsigned int)((sampleFloat + 1.0F) * 2048.0F + 0.5F);
|
||||
|
||||
14
FMControl.h
14
FMControl.h
@@ -19,10 +19,11 @@
|
||||
#if !defined(FMControl_H)
|
||||
#define FMControl_H
|
||||
|
||||
#include "RingBuffer.h"
|
||||
#include "FMNetwork.h"
|
||||
#include "Defines.h"
|
||||
#include "IIRDirectForm1Filter.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "IIR.h"
|
||||
#include "FIR.h"
|
||||
|
||||
// Uncomment this to dump audio to a raw audio file
|
||||
// The file will be written in same folder as executable
|
||||
@@ -52,12 +53,9 @@ private:
|
||||
bool m_begin;
|
||||
|
||||
CRingBuffer<unsigned char> m_incomingRFAudio;
|
||||
|
||||
CIIRDirectForm1Filter* m_preEmphasis;
|
||||
CIIRDirectForm1Filter* m_deEmphasis;
|
||||
CIIRDirectForm1Filter* m_filterStage1;
|
||||
CIIRDirectForm1Filter* m_filterStage2;
|
||||
CIIRDirectForm1Filter* m_filterStage3;
|
||||
CIIR m_preEmphasis;
|
||||
CIIR m_deEmphasis;
|
||||
CFIR m_filter;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2020,2024 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2020 by Geoffrey Merck - F4FXL KC3FRA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,10 +17,11 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "IIRDirectForm1Filter.h"
|
||||
#include "math.h"
|
||||
#include "IIR.h"
|
||||
|
||||
CIIRDirectForm1Filter::CIIRDirectForm1Filter(float b0, float b1, float b2, float , float a1, float a2, float addtionalGaindB) :
|
||||
#include <cmath>
|
||||
|
||||
CIIR::CIIR(float b0, float b1, float b2, float , float a1, float a2, float addtionalGaindB) :
|
||||
m_x2(0.0F),
|
||||
m_y2(0.0F),
|
||||
m_x1(0.0F),
|
||||
@@ -32,29 +33,29 @@ m_a1(a1),
|
||||
m_a2(a2),
|
||||
m_additionalGainLin(0.0F)
|
||||
{
|
||||
m_additionalGainLin = ::powf(10.0F, addtionalGaindB / 20.0F);
|
||||
m_additionalGainLin = ::powf(10.0F, addtionalGaindB / 20.0F);
|
||||
}
|
||||
|
||||
float CIIRDirectForm1Filter::filter(float sample)
|
||||
CIIR::~CIIR()
|
||||
{
|
||||
float output = m_b0 * sample
|
||||
+ m_b1 * m_x1
|
||||
+ m_b2 * m_x2
|
||||
- m_a1 * m_y1
|
||||
- m_a2 * m_y2;
|
||||
|
||||
m_x2 = m_x1;
|
||||
m_y2 = m_y1;
|
||||
m_x1 = sample;
|
||||
m_y1 = output;
|
||||
|
||||
return output * m_additionalGainLin;
|
||||
}
|
||||
|
||||
void CIIRDirectForm1Filter::reset()
|
||||
float CIIR::filter(float sample)
|
||||
{
|
||||
m_x1 = 0.0f;
|
||||
m_x2 = 0.0f;
|
||||
m_y1 = 0.0f;
|
||||
m_y2 = 0.0f;
|
||||
float output = m_b0 * sample + m_b1 * m_x1 + m_b2 * m_x2 - m_a1 * m_y1 - m_a2 * m_y2;
|
||||
|
||||
m_x2 = m_x1;
|
||||
m_y2 = m_y1;
|
||||
m_x1 = sample;
|
||||
m_y1 = output;
|
||||
|
||||
return output * m_additionalGainLin;
|
||||
}
|
||||
|
||||
void CIIR::reset()
|
||||
{
|
||||
m_x1 = 0.0F;
|
||||
m_x2 = 0.0F;
|
||||
m_y1 = 0.0F;
|
||||
m_y2 = 0.0F;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015-2020,2024 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2020 by Geoffrey Merck - F4FXL KC3FRA
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -17,34 +17,33 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(IIRDIRECTFORM1FILTER_H)
|
||||
#define IIRDIRECTFORM1FILTER_H
|
||||
#if !defined(IIR_H)
|
||||
#define IIR_H
|
||||
|
||||
class CIIRDirectForm1Filter
|
||||
class CIIR
|
||||
{
|
||||
public:
|
||||
CIIRDirectForm1Filter(float b0, float b1, float b2, float, float a1, float a2, float additionalGaindB);
|
||||
float filter(float sample);
|
||||
void reset();
|
||||
CIIR(float b0, float b1, float b2, float, float a1, float a2, float additionalGaindB);
|
||||
~CIIR();
|
||||
|
||||
float filter(float sample);
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
// delay line
|
||||
float m_x2; // x[n-2]
|
||||
float m_y2; // y[n-2]
|
||||
float m_x1; // x[n-1]
|
||||
float m_y1; // y[n-1]
|
||||
|
||||
// coefficients
|
||||
// FIR
|
||||
float m_b0;
|
||||
float m_b1;
|
||||
float m_b2;
|
||||
// IIR
|
||||
float m_a1;
|
||||
float m_a2;
|
||||
// Delay line
|
||||
float m_x2; // x[n-2]
|
||||
float m_y2; // y[n-2]
|
||||
float m_x1; // x[n-1]
|
||||
float m_y1; // y[n-1]
|
||||
|
||||
float m_additionalGainLin;
|
||||
// Coefficients
|
||||
float m_b0;
|
||||
float m_b1;
|
||||
float m_b2;
|
||||
float m_a1;
|
||||
float m_a2;
|
||||
float m_additionalGainLin;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -198,6 +198,7 @@
|
||||
<ClInclude Include="DStarHeader.h" />
|
||||
<ClInclude Include="DStarNetwork.h" />
|
||||
<ClInclude Include="DStarSlowData.h" />
|
||||
<ClInclude Include="FIR.h" />
|
||||
<ClInclude Include="FMControl.h" />
|
||||
<ClInclude Include="FMIAXNetwork.h" />
|
||||
<ClInclude Include="FMNetwork.h" />
|
||||
@@ -207,7 +208,7 @@
|
||||
<ClInclude Include="Golay24128.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="DMRLookup.h" />
|
||||
<ClInclude Include="IIRDirectForm1Filter.h" />
|
||||
<ClInclude Include="IIR.h" />
|
||||
<ClInclude Include="LCDproc.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="M17Control.h" />
|
||||
@@ -314,6 +315,7 @@
|
||||
<ClCompile Include="DStarHeader.cpp" />
|
||||
<ClCompile Include="DStarNetwork.cpp" />
|
||||
<ClCompile Include="DStarSlowData.cpp" />
|
||||
<ClCompile Include="FIR.cpp" />
|
||||
<ClCompile Include="FMControl.cpp" />
|
||||
<ClCompile Include="FMIAXNetwork.cpp" />
|
||||
<ClCompile Include="FMNetwork.cpp" />
|
||||
@@ -322,7 +324,7 @@
|
||||
<ClCompile Include="Golay2087.cpp" />
|
||||
<ClCompile Include="Golay24128.cpp" />
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="IIRDirectForm1Filter.cpp" />
|
||||
<ClCompile Include="IIR.cpp" />
|
||||
<ClCompile Include="LCDproc.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="M17Control.cpp" />
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
<ClInclude Include="FMControl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IIRDirectForm1Filter.h">
|
||||
<ClInclude Include="IIR.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PseudoTTYController.h">
|
||||
@@ -356,6 +356,9 @@
|
||||
<ClInclude Include="FMUSRPNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FIR.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RS634717.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -634,7 +637,7 @@
|
||||
<ClCompile Include="FMControl.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IIRDirectForm1Filter.cpp">
|
||||
<ClCompile Include="IIR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PseudoTTYController.cpp">
|
||||
@@ -676,6 +679,9 @@
|
||||
<ClCompile Include="FMUSRPNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FIR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RS634717.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
4
Makefile
4
Makefile
@@ -11,8 +11,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BCH.o AX25Control.o AX25Network.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o \
|
||||
|
||||
@@ -12,8 +12,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o \
|
||||
|
||||
@@ -11,8 +11,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o P25Trellis.o PseudoTTYController.o \
|
||||
|
||||
@@ -11,8 +11,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o \
|
||||
|
||||
@@ -15,8 +15,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o M17CRC.o \
|
||||
M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o OLED.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o P25Trellis.o \
|
||||
|
||||
@@ -12,8 +12,8 @@ LDFLAGS = -g -L/usr/local/lib
|
||||
OBJECTS = \
|
||||
AMBEFEC.o AX25Control.o AX25Network.o BCH.o BPTC19696.o CASTInfo.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o \
|
||||
DMRDirectNetwork.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRGatewayNetwork.o DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FMControl.o FMNetwork.o FMIAXNetwork.o FMRAWNetwork.o \
|
||||
FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIRDirectForm1Filter.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
DMRAccessControl.o DMRTA.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o FIR.o FMControl.o FMNetwork.o FMIAXNetwork.o \
|
||||
FMRAWNetwork.o FMUSRPNetwork.o Golay2087.o Golay24128.o Hamming.o HD44780.o I2CController.o IIR.o LCDproc.o Log.o M17Control.o M17Convolution.o \
|
||||
M17CRC.o M17LSF.o M17Network.o M17Utils.o MMDVMHost.o Modem.o ModemPort.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullController.o NullDisplay.o \
|
||||
NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \
|
||||
NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o P25Trellis.o PseudoTTYController.o \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2021 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2015-2021,2024 Jonathan Naylor, G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -178,6 +178,12 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
|
||||
m_lastFICH = fich;
|
||||
}
|
||||
|
||||
/*
|
||||
LogMessage("RF FICH: FI:%X CS:%X CM:%X BN:%u BT:%u FN:%u FT:%u Dev:%X MR:%X VOIP:%X DT:%X DGId:%X",
|
||||
m_lastFICH.getFI(), m_lastFICH.getCS(), m_lastFICH.getCM(), m_lastFICH.getBN(), m_lastFICH.getBT(),
|
||||
m_lastFICH.getFN(), m_lastFICH.getFT(), m_lastFICH.getDev() ? 1 : 0, m_lastFICH.getMR(), m_lastFICH.getVoIP() ? 1 : 0,
|
||||
m_lastFICH.getDT(), m_lastFICH.getDGId());
|
||||
*/
|
||||
#ifdef notdef
|
||||
// Stop repeater packets coming through, unless we're acting as a remote gateway
|
||||
if (m_remoteGateway) {
|
||||
@@ -238,7 +244,7 @@ bool CYSFControl::processVWData(bool valid, unsigned char *data)
|
||||
}
|
||||
|
||||
unsigned char cm = m_lastFICH.getCM();
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
m_rfDest = (unsigned char*)"ALL ";
|
||||
else
|
||||
m_rfDest = m_rfPayload.getDest();
|
||||
@@ -407,7 +413,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||
}
|
||||
|
||||
unsigned char cm = m_lastFICH.getCM();
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
m_rfDest = (unsigned char*)"ALL ";
|
||||
else
|
||||
m_rfDest = m_rfPayload.getDest();
|
||||
@@ -583,7 +589,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||
return false;
|
||||
|
||||
unsigned char cm = m_lastFICH.getCM();
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
m_rfDest = (unsigned char*)"ALL ";
|
||||
else
|
||||
m_rfDest = m_rfPayload.getDest();
|
||||
@@ -628,7 +634,7 @@ bool CYSFControl::processDNData(bool valid, unsigned char *data)
|
||||
memcpy(csd1 + YSF_CALLSIGN_LENGTH, m_rfSource, YSF_CALLSIGN_LENGTH);
|
||||
memset(csd2, ' ', YSF_CALLSIGN_LENGTH + YSF_CALLSIGN_LENGTH);
|
||||
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
memset(csd1 + 0U, '*', YSF_CALLSIGN_LENGTH);
|
||||
else
|
||||
memcpy(csd1 + 0U, m_rfDest, YSF_CALLSIGN_LENGTH);
|
||||
@@ -709,7 +715,7 @@ bool CYSFControl::processFRData(bool valid, unsigned char *data)
|
||||
}
|
||||
|
||||
unsigned char cm = m_lastFICH.getCM();
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
m_rfDest = (unsigned char*)"ALL ";
|
||||
else
|
||||
m_rfDest = m_rfPayload.getDest();
|
||||
@@ -921,6 +927,14 @@ void CYSFControl::writeNetwork()
|
||||
if (valid)
|
||||
dgid = fich.getDGId();
|
||||
|
||||
/*
|
||||
if (valid)
|
||||
LogMessage("Net FICH: FI:%X CS:%X CM:%X BN:%u BT:%u FN:%u FT:%u Dev:%X MR:%X VOIP:%X DT:%X DGId:%X",
|
||||
fich.getFI(), fich.getCS(), fich.getCM(), fich.getBN(), fich.getBT(),
|
||||
fich.getFN(), fich.getFT(), fich.getDev() ? 1 : 0, fich.getMR(), fich.getVoIP() ? 1 : 0,
|
||||
fich.getDT(), fich.getDGId());
|
||||
*/
|
||||
|
||||
if (!m_netTimeoutTimer.isRunning()) {
|
||||
if (end)
|
||||
return;
|
||||
@@ -960,7 +974,7 @@ void CYSFControl::writeNetwork()
|
||||
unsigned char cm = fich.getCM();
|
||||
|
||||
if (::memcmp(m_netDest, " ", YSF_CALLSIGN_LENGTH) == 0) {
|
||||
if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2)
|
||||
if (cm == YSF_CM_GROUP_CQ || cm == YSF_CM_RADIO_ID)
|
||||
::memcpy(m_netDest, "ALL ", YSF_CALLSIGN_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
16
YSFDefines.h
16
YSFDefines.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2024 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -37,15 +37,21 @@ const unsigned char YSF_FI_COMMUNICATIONS = 0x01U;
|
||||
const unsigned char YSF_FI_TERMINATOR = 0x02U;
|
||||
const unsigned char YSF_FI_TEST = 0x03U;
|
||||
|
||||
const unsigned char YSF_CS_RESERVE1 = 0x00U;
|
||||
const unsigned char YSF_CS_RESERVE2 = 0x01U;
|
||||
const unsigned char YSF_CS_ASSIGN = 0x02U;
|
||||
const unsigned char YSF_CS_RESERVE3 = 0x03U;
|
||||
|
||||
const unsigned char YSF_CM_GROUP_CQ = 0x00U;
|
||||
const unsigned char YSF_CM_RADIO_ID = 0x01U;
|
||||
const unsigned char YSF_CM_RESERVE = 0x02U;
|
||||
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||
|
||||
const unsigned char YSF_DT_VD_MODE1 = 0x00U;
|
||||
const unsigned char YSF_DT_DATA_FR_MODE = 0x01U;
|
||||
const unsigned char YSF_DT_VD_MODE2 = 0x02U;
|
||||
const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U;
|
||||
|
||||
const unsigned char YSF_CM_GROUP1 = 0x00U;
|
||||
const unsigned char YSF_CM_GROUP2 = 0x01U;
|
||||
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||
|
||||
const unsigned char YSF_MR_DIRECT = 0x00U;
|
||||
const unsigned char YSF_MR_NOT_BUSY = 0x01U;
|
||||
const unsigned char YSF_MR_BUSY = 0x02U;
|
||||
|
||||
48
YSFFICH.cpp
48
YSFFICH.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017,2019,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2019,2020,2021,2024 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -178,6 +178,11 @@ unsigned char CYSFFICH::getFI() const
|
||||
return (m_fich[0U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getCS() const
|
||||
{
|
||||
return (m_fich[0U] >> 4) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getCM() const
|
||||
{
|
||||
return (m_fich[0U] >> 2) & 0x03U;
|
||||
@@ -203,9 +208,9 @@ unsigned char CYSFFICH::getFT() const
|
||||
return m_fich[1U] & 0x07U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getDT() const
|
||||
bool CYSFFICH::getDev() const
|
||||
{
|
||||
return m_fich[2U] & 0x03U;
|
||||
return (m_fich[2U] & 0x40U) == 0x40U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getMR() const
|
||||
@@ -213,9 +218,14 @@ unsigned char CYSFFICH::getMR() const
|
||||
return (m_fich[2U] >> 3) & 0x03U;
|
||||
}
|
||||
|
||||
bool CYSFFICH::getDev() const
|
||||
bool CYSFFICH::getVoIP() const
|
||||
{
|
||||
return (m_fich[2U] & 0x40U) == 0x40U;
|
||||
return (m_fich[2U] & 0x04U) == 0x04U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getDT() const
|
||||
{
|
||||
return m_fich[2U] & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getDGId() const
|
||||
@@ -229,6 +239,18 @@ void CYSFFICH::setFI(unsigned char fi)
|
||||
m_fich[0U] |= (fi << 6) & 0xC0U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setCS(unsigned char cs)
|
||||
{
|
||||
m_fich[0U] &= 0xCFU;
|
||||
m_fich[0U] |= (cs << 4) & 0x30U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setCM(unsigned char cm)
|
||||
{
|
||||
m_fich[0U] &= 0xF3U;
|
||||
m_fich[0U] |= (cm << 2) & 0x0CU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setBN(unsigned char bn)
|
||||
{
|
||||
m_fich[0U] &= 0xFCU;
|
||||
@@ -253,6 +275,14 @@ void CYSFFICH::setFT(unsigned char ft)
|
||||
m_fich[1U] |= ft & 0x07U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDev(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x40U;
|
||||
else
|
||||
m_fich[2U] &= 0xBFU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setMR(unsigned char mr)
|
||||
{
|
||||
m_fich[2U] &= 0xC7U;
|
||||
@@ -267,12 +297,10 @@ void CYSFFICH::setVoIP(bool on)
|
||||
m_fich[2U] &= 0xFBU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDev(bool on)
|
||||
void CYSFFICH::setDT(unsigned char dt)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x40U;
|
||||
else
|
||||
m_fich[2U] &= 0xBFU;
|
||||
m_fich[2U] &= 0xFCU;
|
||||
m_fich[2U] |= dt & 0x03U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDGId(unsigned char id)
|
||||
|
||||
13
YSFFICH.h
13
YSFFICH.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017,2019,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017,2019,2020,2024 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -30,24 +30,29 @@ public:
|
||||
void encode(unsigned char* bytes);
|
||||
|
||||
unsigned char getFI() const;
|
||||
unsigned char getCS() const;
|
||||
unsigned char getCM() const;
|
||||
unsigned char getBN() const;
|
||||
unsigned char getBT() const;
|
||||
unsigned char getFN() const;
|
||||
unsigned char getFT() const;
|
||||
unsigned char getDT() const;
|
||||
bool getDev() const;
|
||||
unsigned char getMR() const;
|
||||
bool getDev() const;
|
||||
bool getVoIP() const;
|
||||
unsigned char getDT() const;
|
||||
unsigned char getDGId() const;
|
||||
|
||||
void setFI(unsigned char fi);
|
||||
void setCS(unsigned char cs);
|
||||
void setCM(unsigned char cm);
|
||||
void setBN(unsigned char bn);
|
||||
void setBT(unsigned char bt);
|
||||
void setFN(unsigned char fn);
|
||||
void setFT(unsigned char ft);
|
||||
void setDev(bool set);
|
||||
void setMR(unsigned char mr);
|
||||
void setVoIP(bool set);
|
||||
void setDev(bool set);
|
||||
void setDT(unsigned char dt);
|
||||
void setDGId(unsigned char id);
|
||||
|
||||
CYSFFICH& operator=(const CYSFFICH& fich);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017,2020 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016,2017,2020,2024 Jonathan Naylor, G4KLX
|
||||
* Copyright (C) 2016 Mathias Weyland, HB9FRV
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -304,6 +304,7 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool
|
||||
|
||||
switch (fn) {
|
||||
case 0U:
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, CSD1", output, 20U);
|
||||
if (m_dest == NULL) {
|
||||
m_dest = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
::memcpy(m_dest, output + 0U, YSF_CALLSIGN_LENGTH);
|
||||
@@ -317,6 +318,7 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, CSD2", output, 20U);
|
||||
if (m_downlink != NULL && !gateway)
|
||||
::memcpy(output + 0U, m_downlink, YSF_CALLSIGN_LENGTH);
|
||||
|
||||
@@ -325,24 +327,28 @@ bool CYSFPayload::processVDMode1Data(unsigned char* data, unsigned char fn, bool
|
||||
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, CSD3", output, 20U);
|
||||
break;
|
||||
|
||||
case 3U:
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data, DT1", output, 20U);
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, DT1", output, 20U);
|
||||
break;
|
||||
|
||||
case 4U:
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data, DT2", output, 20U);
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, DT2", output, 20U);
|
||||
break;
|
||||
|
||||
case 5U:
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data, DT3", output, 20U);
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, DT3", output, 20U);
|
||||
break;
|
||||
|
||||
case 6U:
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data, DT4", output, 20U);
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, DT4", output, 20U);
|
||||
break;
|
||||
|
||||
case 7U:
|
||||
// CUtils::dump(1U, "V/D Mode 1 Data, DT5", output, 20U);
|
||||
// CUtils::dump(2U, "V/D Mode 1 Data, DT5", output, 20U);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -502,6 +508,7 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool
|
||||
|
||||
switch (fn) {
|
||||
case 0U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Dest", output, YSF_CALLSIGN_LENGTH);
|
||||
if (m_dest == NULL) {
|
||||
m_dest = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
::memcpy(m_dest, output, YSF_CALLSIGN_LENGTH);
|
||||
@@ -509,6 +516,7 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool
|
||||
break;
|
||||
|
||||
case 1U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Src", output, YSF_CALLSIGN_LENGTH);
|
||||
if (m_source == NULL) {
|
||||
m_source = new unsigned char[YSF_CALLSIGN_LENGTH];
|
||||
::memcpy(m_source, output, YSF_CALLSIGN_LENGTH);
|
||||
@@ -516,21 +524,31 @@ bool CYSFPayload::processVDMode2Data(unsigned char* data, unsigned char fn, bool
|
||||
break;
|
||||
|
||||
case 2U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Down", output, YSF_CALLSIGN_LENGTH);
|
||||
if (m_downlink != NULL && !gateway)
|
||||
::memcpy(output, m_downlink, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
case 3U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Up", output, YSF_CALLSIGN_LENGTH);
|
||||
if (m_uplink != NULL && !gateway)
|
||||
::memcpy(output, m_uplink, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
case 4U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Rem1+2", output, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
case 5U:
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, Rem3+4", output, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
case 6U:
|
||||
// CUtils::dump(1U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH);
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, DT1", output, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
case 7U:
|
||||
// CUtils::dump(1U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH);
|
||||
// CUtils::dump(2U, "V/D Mode 2 Data, DT2", output, YSF_CALLSIGN_LENGTH);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user