Add FM network audio gain and optional pre- and de-emphasis.

This commit is contained in:
Jonathan Naylor 2021-03-14 14:59:34 +00:00
parent fb0d1ef5e2
commit 75e8e95aad
8 changed files with 147 additions and 74 deletions

View file

@ -283,12 +283,16 @@ m_pocsagLocalPort(0U),
m_pocsagNetworkModeHang(3U), m_pocsagNetworkModeHang(3U),
m_pocsagNetworkDebug(false), m_pocsagNetworkDebug(false),
m_fmNetworkEnabled(false), m_fmNetworkEnabled(false),
m_fmNetworkFormat("MMDVM"), m_fmNetworkProtocol("MMDVM"),
m_fmGatewayAddress(), m_fmGatewayAddress(),
m_fmGatewayPort(0U), m_fmGatewayPort(0U),
m_fmLocalAddress(), m_fmLocalAddress(),
m_fmLocalPort(0U), m_fmLocalPort(0U),
m_fmSampleRate(8000U), m_fmSampleRate(8000U),
m_fmPreEmphasis(true),
m_fmDeEmphasis(true),
m_fmTXAudioGain(1.0F),
m_fmRXAudioGain(1.0F),
m_fmNetworkModeHang(3U), m_fmNetworkModeHang(3U),
m_fmNetworkDebug(false), m_fmNetworkDebug(false),
m_ax25NetworkEnabled(false), m_ax25NetworkEnabled(false),
@ -999,8 +1003,8 @@ bool CConf::read()
} else if (section == SECTION_FM_NETWORK) { } else if (section == SECTION_FM_NETWORK) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
m_fmNetworkEnabled = ::atoi(value) == 1; m_fmNetworkEnabled = ::atoi(value) == 1;
else if (::strcmp(key, "Format") == 0) else if (::strcmp(key, "Protocol") == 0)
m_fmNetworkFormat = value; m_fmNetworkProtocol = value;
else if (::strcmp(key, "LocalAddress") == 0) else if (::strcmp(key, "LocalAddress") == 0)
m_fmLocalAddress = value; m_fmLocalAddress = value;
else if (::strcmp(key, "LocalPort") == 0) else if (::strcmp(key, "LocalPort") == 0)
@ -1011,6 +1015,14 @@ bool CConf::read()
m_fmGatewayPort = (unsigned int)::atoi(value); m_fmGatewayPort = (unsigned int)::atoi(value);
else if (::strcmp(key, "SampleRate") == 0) else if (::strcmp(key, "SampleRate") == 0)
m_fmSampleRate = (unsigned int)::atoi(value); m_fmSampleRate = (unsigned int)::atoi(value);
else if (::strcmp(key, "PreEmphasis") == 0)
m_fmPreEmphasis = ::atoi(value) == 1;
else if (::strcmp(key, "DeEmphasis") == 0)
m_fmDeEmphasis = ::atoi(value) == 1;
else if (::strcmp(key, "TXAudioGain") == 0)
m_fmTXAudioGain = float(::atof(value));
else if (::strcmp(key, "RXAudioGain") == 0)
m_fmRXAudioGain = float(::atof(value));
else if (::strcmp(key, "ModeHang") == 0) else if (::strcmp(key, "ModeHang") == 0)
m_fmNetworkModeHang = (unsigned int)::atoi(value); m_fmNetworkModeHang = (unsigned int)::atoi(value);
else if (::strcmp(key, "Debug") == 0) else if (::strcmp(key, "Debug") == 0)
@ -2200,9 +2212,9 @@ bool CConf::getFMNetworkEnabled() const
return m_fmNetworkEnabled; return m_fmNetworkEnabled;
} }
std::string CConf::getFMNetworkFormat() const std::string CConf::getFMNetworkProtocol() const
{ {
return m_fmNetworkFormat; return m_fmNetworkProtocol;
} }
std::string CConf::getFMGatewayAddress() const std::string CConf::getFMGatewayAddress() const
@ -2230,6 +2242,26 @@ unsigned int CConf::getFMSampleRate() const
return m_fmSampleRate; return m_fmSampleRate;
} }
bool CConf::getFMPreEmphasis() const
{
return m_fmPreEmphasis;
}
bool CConf::getFMDeEmphasis() const
{
return m_fmDeEmphasis;
}
float CConf::getFMTXAudioGain() const
{
return m_fmTXAudioGain;
}
float CConf::getFMRXAudioGain() const
{
return m_fmRXAudioGain;
}
unsigned int CConf::getFMNetworkModeHang() const unsigned int CConf::getFMNetworkModeHang() const
{ {
return m_fmNetworkModeHang; return m_fmNetworkModeHang;

12
Conf.h
View file

@ -296,12 +296,16 @@ public:
// The FM Network section // The FM Network section
bool getFMNetworkEnabled() const; bool getFMNetworkEnabled() const;
std::string getFMNetworkFormat() const; std::string getFMNetworkProtocol() const;
std::string getFMGatewayAddress() const; std::string getFMGatewayAddress() const;
unsigned int getFMGatewayPort() const; unsigned int getFMGatewayPort() const;
std::string getFMLocalAddress() const; std::string getFMLocalAddress() const;
unsigned int getFMLocalPort() const; unsigned int getFMLocalPort() const;
unsigned int getFMSampleRate() const; unsigned int getFMSampleRate() const;
bool getFMPreEmphasis() const;
bool getFMDeEmphasis() const;
float getFMTXAudioGain() const;
float getFMRXAudioGain() const;
unsigned int getFMNetworkModeHang() const; unsigned int getFMNetworkModeHang() const;
bool getFMNetworkDebug() const; bool getFMNetworkDebug() const;
@ -604,12 +608,16 @@ private:
bool m_pocsagNetworkDebug; bool m_pocsagNetworkDebug;
bool m_fmNetworkEnabled; bool m_fmNetworkEnabled;
std::string m_fmNetworkFormat; std::string m_fmNetworkProtocol;
std::string m_fmGatewayAddress; std::string m_fmGatewayAddress;
unsigned int m_fmGatewayPort; unsigned int m_fmGatewayPort;
std::string m_fmLocalAddress; std::string m_fmLocalAddress;
unsigned int m_fmLocalPort; unsigned int m_fmLocalPort;
unsigned int m_fmSampleRate; unsigned int m_fmSampleRate;
bool m_fmPreEmphasis;
bool m_fmDeEmphasis;
float m_fmTXAudioGain;
float m_fmRXAudioGain;
unsigned int m_fmNetworkModeHang; unsigned int m_fmNetworkModeHang;
bool m_fmNetworkDebug; bool m_fmNetworkDebug;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020 by Jonathan Naylor G4KLX * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -31,20 +31,27 @@ const float PREEMPHASIS_GAIN_DB = 0.0F; // Audio gain adjustment
const float FILTER_GAIN_DB = 2.0F; // Audio gain adjustment const float FILTER_GAIN_DB = 2.0F; // Audio gain adjustment
const unsigned int FM_MASK = 0x00000FFFU; const unsigned int FM_MASK = 0x00000FFFU;
CFMControl::CFMControl(CFMNetwork* network) : CFMControl::CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn) :
m_network(network), m_network(network),
m_txAudioGain(txAudioGain),
m_rxAudioGain(rxAudioGain),
m_preEmphasisOn(preEmphasisOn),
m_deEmphasisOn(deEmphasisOn),
m_enabled(false), m_enabled(false),
m_incomingRFAudio(1600U, "Incoming RF FM Audio"), m_incomingRFAudio(1600U, "Incoming RF FM Audio"),
m_preemphasis (NULL), m_preEmphasis(NULL),
m_deemphasis (NULL), m_deEmphasis(NULL),
m_filterStage1(NULL), m_filterStage1(NULL),
m_filterStage2(NULL), m_filterStage2(NULL),
m_filterStage3(NULL) m_filterStage3(NULL)
{ {
m_preemphasis = new CIIRDirectForm1Filter(8.315375384336983F,-7.03334621603483F,0.0F,1.0F,0.282029168302153F,0.0F, PREEMPHASIS_GAIN_DB); assert(txAudioGain > 0.0F);
m_deemphasis = new CIIRDirectForm1Filter(0.07708787090460224F,0.07708787090460224F,0.0F,1.0F,-0.8458242581907955F,0.0F, DEEMPHASIS_GAIN_DB); assert(rxAudioGain > 0.0F);
//cheby type 1 0.2dB cheby type 1 3rd order 300-2700Hz fs=8000 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_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_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); m_filterStage3 = new CIIRDirectForm1Filter(1.0f, -2.0f, 1.0f, 1.0f, -1.8414584f, 0.8804949f, FILTER_GAIN_DB);
@ -52,8 +59,8 @@ m_filterStage3(NULL)
CFMControl::~CFMControl() CFMControl::~CFMControl()
{ {
delete m_preemphasis ; delete m_preEmphasis;
delete m_deemphasis ; delete m_deEmphasis;
delete m_filterStage1; delete m_filterStage1;
delete m_filterStage2; delete m_filterStage2;
@ -79,42 +86,45 @@ bool CFMControl::writeModem(const unsigned char* data, unsigned int length)
m_incomingRFAudio.addData(data + 1U, length - 1U); m_incomingRFAudio.addData(data + 1U, length - 1U);
unsigned int bufferLength = m_incomingRFAudio.dataSize(); unsigned int bufferLength = m_incomingRFAudio.dataSize();
if (bufferLength > 240U) //160 samples 12-bit if (bufferLength > 240U) // 160 samples 12-bit
bufferLength = 240U; //160 samples 12-bit bufferLength = 240U; // 160 samples 12-bit
if (bufferLength >= 3U) { if (bufferLength >= 3U) {
bufferLength = bufferLength - bufferLength % 3U; //round down to nearest multiple of 3 bufferLength = bufferLength - bufferLength % 3U; // Round down to nearest multiple of 3
unsigned char bufferData[240U]; //160 samples 12-bit unsigned char bufferData[240U]; // 160 samples 12-bit
m_incomingRFAudio.getData(bufferData, bufferLength); m_incomingRFAudio.getData(bufferData, bufferLength);
unsigned int pack = 0U; unsigned int pack = 0U;
unsigned char* packPointer = (unsigned char*)&pack; unsigned char* packPointer = (unsigned char*)&pack;
float out[160U]; //160 samples 12-bit float out[160U]; // 160 samples 12-bit
unsigned int nOut = 0U; unsigned int nOut = 0U;
short unpackedSamples[2U]; short unpackedSamples[2U];
for (unsigned int i = 0U; i < bufferLength; i += 3U) { for (unsigned int i = 0U; i < bufferLength; i += 3U) {
//extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed // Extract unsigned 12 bit unsigned sample pairs packed into 3 bytes to 16 bit signed
packPointer[0U] = bufferData[i]; packPointer[0U] = bufferData[i + 0U];
packPointer[1U] = bufferData[i + 1U]; packPointer[1U] = bufferData[i + 1U];
packPointer[2U] = bufferData[i + 2U]; packPointer[2U] = bufferData[i + 2U];
unpackedSamples[1U] = short(int(pack & FM_MASK) - 2048); unpackedSamples[1U] = short(int(pack & FM_MASK) - 2048);
unpackedSamples[0U] = short(int(pack >> 12 & FM_MASK) - 2048); // unpackedSamples[0U] = short(int(pack >> 12 & FM_MASK) - 2048); //
//process unpacked sample pair // Process unpacked sample pair
for (unsigned char j = 0U; j < 2U; j++) { for (unsigned char j = 0U; j < 2U; j++) {
// Convert to float (-1.0 to +1.0) // Convert to float (-1.0 to +1.0)
float sampleFloat = float(unpackedSamples[j]) / 2048.0F; float sampleFloat = (float(unpackedSamples[j]) * m_rxAudioGain) / 2048.0F;
// De-emphasise and remove CTCSS // De-emphasise and remove CTCSS
sampleFloat = m_deemphasis->filter(sampleFloat); if (m_deEmphasisOn)
sampleFloat = m_deEmphasis->filter(sampleFloat);
out[nOut++] = m_filterStage3->filter(m_filterStage2->filter(m_filterStage1->filter(sampleFloat))); out[nOut++] = m_filterStage3->filter(m_filterStage2->filter(m_filterStage1->filter(sampleFloat)));
} }
} }
#if defined(DUMP_RF_AUDIO) #if defined(DUMP_RF_AUDIO)
FILE * audiofile = fopen("./audiodump.bin", "ab"); FILE * audiofile = fopen("./audiodump.bin", "ab");
if(audiofile != NULL) { if (audiofile != NULL) {
fwrite(out, sizeof(float), nOut, audiofile); fwrite(out, sizeof(float), nOut, audiofile);
fclose(audiofile); fclose(audiofile);
} }
@ -133,8 +143,8 @@ unsigned int CFMControl::readModem(unsigned char* data, unsigned int space)
if (m_network == NULL) if (m_network == NULL)
return 0U; return 0U;
if (space > 240U) //160 samples 12-bit if (space > 240U) // 160 samples 12-bit
space = 240U; //160 samples 12-bit space = 240U; // 160 samples 12-bit
float netData[160U]; // Modem can handle up to 160 samples at a time float netData[160U]; // Modem can handle up to 160 samples at a time
unsigned int length = m_network->read(netData, 160U); //160 samples 12-bit unsigned int length = m_network->read(netData, 160U); //160 samples 12-bit
@ -146,14 +156,17 @@ unsigned int CFMControl::readModem(unsigned char* data, unsigned int space)
unsigned int nData = 0U; unsigned int nData = 0U;
for (unsigned int i = 0; i < length; i++) { for (unsigned int i = 0; i < length; i++) {
float sampleFloat = netData[i] * m_txAudioGain;
// Pre-emphasis // Pre-emphasis
float sampleFloat = m_preemphasis->filter(netData[i]); if (m_preEmphasisOn)
sampleFloat = m_preEmphasis->filter(sampleFloat);
// Convert float to 12-bit samples (0 to 4095) // Convert float to 12-bit samples (0 to 4095)
unsigned int sample12bit = (unsigned int)((sampleFloat + 1.0F) * 2048.0F + 0.5F); unsigned int sample12bit = (unsigned int)((sampleFloat + 1.0F) * 2048.0F + 0.5F);
// pack 2 samples onto 3 bytes // Pack 2 samples into 3 bytes
if((i & 1U) == 0) { if ((i & 1U) == 0) {
pack = 0U; pack = 0U;
pack = sample12bit << 12; pack = sample12bit << 12;
} else { } else {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020 by Jonathan Naylor G4KLX * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
class CFMControl { class CFMControl {
public: public:
CFMControl(CFMNetwork* network); CFMControl(CFMNetwork* network, float txAudioGain, float rxAudioGain, bool preEmphasisOn, bool deEmphasisOn);
~CFMControl(); ~CFMControl();
bool writeModem(const unsigned char* data, unsigned int length); bool writeModem(const unsigned char* data, unsigned int length);
@ -43,10 +43,14 @@ public:
private: private:
CFMNetwork* m_network; CFMNetwork* m_network;
float m_txAudioGain;
float m_rxAudioGain;
bool m_preEmphasisOn;
bool m_deEmphasisOn;
bool m_enabled; bool m_enabled;
CRingBuffer<unsigned char> m_incomingRFAudio; CRingBuffer<unsigned char> m_incomingRFAudio;
CIIRDirectForm1Filter* m_preemphasis; CIIRDirectForm1Filter* m_preEmphasis;
CIIRDirectForm1Filter* m_deemphasis; CIIRDirectForm1Filter* m_deEmphasis;
CIIRDirectForm1Filter* m_filterStage1; CIIRDirectForm1Filter* m_filterStage1;
CIIRDirectForm1Filter* m_filterStage2; CIIRDirectForm1Filter* m_filterStage2;
CIIRDirectForm1Filter* m_filterStage3; CIIRDirectForm1Filter* m_filterStage3;

View file

@ -27,8 +27,8 @@
const unsigned int BUFFER_LENGTH = 500U; const unsigned int BUFFER_LENGTH = 500U;
CFMNetwork::CFMNetwork(const std::string& format, const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int sampleRate, bool debug) : CFMNetwork::CFMNetwork(const std::string& protocol, const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int sampleRate, bool debug) :
m_format(FMF_MMDVM), m_protocol(FMNP_MMDVM),
m_socket(localAddress, localPort), m_socket(localAddress, localPort),
m_addr(), m_addr(),
m_addrLen(0U), m_addrLen(0U),
@ -46,8 +46,8 @@ m_seqNo(0U)
if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0)
m_addrLen = 0U; m_addrLen = 0U;
if (format == "USRP") if (protocol == "USRP")
m_format = FMF_USRP; m_protocol = FMNP_USRP;
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
int error; int error;
@ -116,7 +116,7 @@ bool CFMNetwork::writeData(float* data, unsigned int nSamples)
unsigned int length = 0U; unsigned int length = 0U;
if (m_format == FMF_USRP) { if (m_protocol == FMNP_USRP) {
buffer[length++] = 'U'; buffer[length++] = 'U';
buffer[length++] = 'S'; buffer[length++] = 'S';
buffer[length++] = 'R'; buffer[length++] = 'R';
@ -187,7 +187,7 @@ bool CFMNetwork::writeData(float* data, unsigned int nSamples)
bool CFMNetwork::writeEOT() bool CFMNetwork::writeEOT()
{ {
if (m_format == FMF_MMDVM) { if (m_protocol == FMNP_MMDVM) {
unsigned char buffer[10U]; unsigned char buffer[10U];
::memset(buffer, 0x00U, 10U); ::memset(buffer, 0x00U, 10U);
@ -220,11 +220,11 @@ void CFMNetwork::clock(unsigned int ms)
if (length <= 0) if (length <= 0)
return; return;
// Check if the data is for us // does not accept data from USRP // Check if the data is for us
//if (!CUDPSocket::match(addr, m_addr)) { if (!CUDPSocket::match(addr, m_addr)) {
// LogMessage("FM packet received from an invalid source"); LogMessage("FM packet received from an invalid source");
// return; return;
//} }
if (!m_enabled) if (!m_enabled)
return; return;
@ -232,7 +232,7 @@ void CFMNetwork::clock(unsigned int ms)
if (m_debug) if (m_debug)
CUtils::dump(1U, "FM Network Data Received", buffer, length); CUtils::dump(1U, "FM Network Data Received", buffer, length);
if (m_format == FMF_USRP) { if (m_protocol == FMNP_USRP) {
// Invalid packet type? // Invalid packet type?
if (::memcmp(buffer, "USRP", 4U) != 0) if (::memcmp(buffer, "USRP", 4U) != 0)
return; return;
@ -304,9 +304,9 @@ unsigned int CFMNetwork::read(float* data, unsigned int nSamples)
} else { } else {
#endif #endif
for (unsigned int i = 0U; i < nSamples; i++) { for (unsigned int i = 0U; i < nSamples; i++) {
short val = ((buffer[i * 2U + 0U] & 0xFFU) << 0) + // Changing audio format from U16BE to S16LE short val = ((buffer[i * 2U + 0U] & 0xFFU) << 0) +
((buffer[i * 2U + 1U] & 0xFFU) << 8); // Changing audio format from U16BE to S16LE ((buffer[i * 2U + 1U] & 0xFFU) << 8);
data[i] = (float(val) / 65536.0F); // Changing audio format from U16BE to S16LE data[i] = float(val) / 65536.0F;
} }
return nSamples; return nSamples;
@ -347,7 +347,7 @@ void CFMNetwork::enable(bool enabled)
void CFMNetwork::writePoll() void CFMNetwork::writePoll()
{ {
if (m_format == FMF_MMDVM) { if (m_protocol == FMNP_MMDVM) {
unsigned char buffer[3U]; unsigned char buffer[3U];
buffer[0U] = 'F'; buffer[0U] = 'F';

View file

@ -30,14 +30,14 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
enum FM_FORMAT { enum FM_NETWORK_PROTOCOL {
FMF_MMDVM, FMNP_MMDVM,
FMF_USRP FMNP_USRP
}; };
class CFMNetwork { class CFMNetwork {
public: public:
CFMNetwork(const std::string& format, const std::string& myAddress, unsigned int myPort, const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int sampleRate, bool debug); CFMNetwork(const std::string& protocol, const std::string& myAddress, unsigned int myPort, const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int sampleRate, bool debug);
~CFMNetwork(); ~CFMNetwork();
bool open(); bool open();
@ -57,19 +57,19 @@ public:
void clock(unsigned int ms); void clock(unsigned int ms);
private: private:
FM_FORMAT m_format; FM_NETWORK_PROTOCOL m_protocol;
CUDPSocket m_socket; CUDPSocket m_socket;
sockaddr_storage m_addr; sockaddr_storage m_addr;
unsigned int m_addrLen; unsigned int m_addrLen;
unsigned int m_sampleRate; unsigned int m_sampleRate;
bool m_debug; bool m_debug;
bool m_enabled; bool m_enabled;
CRingBuffer<unsigned char> m_buffer; CRingBuffer<unsigned char> m_buffer;
CTimer m_pollTimer; CTimer m_pollTimer;
unsigned int m_seqNo; unsigned int m_seqNo;
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
SRC_STATE* m_incoming; SRC_STATE* m_incoming;
SRC_STATE* m_outgoing; SRC_STATE* m_outgoing;
#endif #endif
void writePoll(); void writePoll();

View file

@ -276,12 +276,16 @@ Debug=0
[FM Network] [FM Network]
Enable=1 Enable=1
# Values are MMDVM and USRP # Values are MMDVM and USRP
Format=USRP Protocol=USRP
LocalAddress=127.0.0.1 LocalAddress=127.0.0.1
LocalPort=3810 LocalPort=3810
GatewayAddress=127.0.0.1 GatewayAddress=127.0.0.1
GatewayPort=4810 GatewayPort=4810
SampleRate=8000 SampleRate=8000
PreEmphasis=1
DeEmphasis=1
TXAudioGain=1.0
RXAudioGain=1.0
# ModeHang=3 # ModeHang=3
Debug=0 Debug=0

View file

@ -681,15 +681,19 @@ int CMMDVMHost::run()
} }
if (m_fmEnabled) { if (m_fmEnabled) {
m_fmRFModeHang = m_conf.getFMModeHang(); bool preEmphasis = m_conf.getFMPreEmphasis();
bool deEmphasis = m_conf.getFMDeEmphasis();
float txAudioGain = m_conf.getFMTXAudioGain();
float rxAudioGain = m_conf.getFMRXAudioGain();
m_fmRFModeHang = m_conf.getFMModeHang();
m_fm = new CFMControl(m_fmNetwork); m_fm = new CFMControl(m_fmNetwork, txAudioGain, rxAudioGain, preEmphasis, deEmphasis);
} }
bool remoteControlEnabled = m_conf.getRemoteControlEnabled(); bool remoteControlEnabled = m_conf.getRemoteControlEnabled();
if (remoteControlEnabled) { if (remoteControlEnabled) {
std::string address = m_conf.getRemoteControlAddress(); std::string address = m_conf.getRemoteControlAddress();
unsigned int port = m_conf.getRemoteControlPort(); unsigned int port = m_conf.getRemoteControlPort();
LogInfo("Remote Control Parameters"); LogInfo("Remote Control Parameters");
LogInfo(" Address: %s", address.c_str()); LogInfo(" Address: %s", address.c_str());
@ -1796,25 +1800,33 @@ bool CMMDVMHost::createPOCSAGNetwork()
bool CMMDVMHost::createFMNetwork() bool CMMDVMHost::createFMNetwork()
{ {
std::string format = m_conf.getFMNetworkFormat(); std::string protocol = m_conf.getFMNetworkProtocol();
std::string gatewayAddress = m_conf.getFMGatewayAddress(); std::string gatewayAddress = m_conf.getFMGatewayAddress();
unsigned int gatewayPort = m_conf.getFMGatewayPort(); unsigned int gatewayPort = m_conf.getFMGatewayPort();
std::string localAddress = m_conf.getFMLocalAddress(); std::string localAddress = m_conf.getFMLocalAddress();
unsigned int localPort = m_conf.getFMLocalPort(); unsigned int localPort = m_conf.getFMLocalPort();
unsigned int sampleRate = m_conf.getFMSampleRate(); unsigned int sampleRate = m_conf.getFMSampleRate();
bool preEmphasis = m_conf.getFMPreEmphasis();
bool deEmphasis = m_conf.getFMDeEmphasis();
float txAudioGain = m_conf.getFMTXAudioGain();
float rxAudioGain = m_conf.getFMRXAudioGain();
m_fmNetModeHang = m_conf.getFMNetworkModeHang(); m_fmNetModeHang = m_conf.getFMNetworkModeHang();
bool debug = m_conf.getFMNetworkDebug(); bool debug = m_conf.getFMNetworkDebug();
LogInfo("FM Network Parameters"); LogInfo("FM Network Parameters");
LogInfo(" Format: %s", format.c_str()); LogInfo(" Protocol: %s", protocol.c_str());
LogInfo(" Gateway Address: %s", gatewayAddress.c_str()); LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
LogInfo(" Gateway Port: %u", gatewayPort); LogInfo(" Gateway Port: %u", gatewayPort);
LogInfo(" Local Address: %s", localAddress.c_str()); LogInfo(" Local Address: %s", localAddress.c_str());
LogInfo(" Local Port: %u", localPort); LogInfo(" Local Port: %u", localPort);
LogInfo(" Sample Rate: %u", sampleRate); LogInfo(" Sample Rate: %u", sampleRate);
LogInfo(" Pre-Emphasis: %s", preEmphasis ? "yes" : "no");
LogInfo(" De-Emphasis: %s", deEmphasis ? "yes" : "no");
LogInfo(" TX Audio Gain: %.2f", txAudioGain);
LogInfo(" RX Audio Gain: %.2f", rxAudioGain);
LogInfo(" Mode Hang: %us", m_fmNetModeHang); LogInfo(" Mode Hang: %us", m_fmNetModeHang);
m_fmNetwork = new CFMNetwork(format, localAddress, localPort, gatewayAddress, gatewayPort, sampleRate, debug); m_fmNetwork = new CFMNetwork(protocol, localAddress, localPort, gatewayAddress, gatewayPort, sampleRate, debug);
bool ret = m_fmNetwork->open(); bool ret = m_fmNetwork->open();
if (!ret) { if (!ret) {