kopia lustrzana https://github.com/jamescoxon/dl-fldigi
DTMF encoder
* Added DTMF encoder accessible as a macro tag - <DTMF:string of chars> where string of chars can contain 0..9,space,-,comma,*,#,A..D - space, hyphen and comma insert a 50 msec silent period in the transmissionspull/1/head
rodzic
4942a0b2da
commit
3113c68de8
|
@ -608,6 +608,7 @@
|
|||
"Single tone at center of modem BW, carrier detect for amplifiers", \
|
||||
0.0) \
|
||||
ELEM_(bool, macroCWid, "", "", false) \
|
||||
ELEM_(std::string, DTMFstr, "", "", "") \
|
||||
ELEM_(int, videowidth, "VIDEOWIDTH", \
|
||||
"Video ID text width (characters per row)", \
|
||||
1) \
|
||||
|
|
|
@ -65,6 +65,9 @@ protected:
|
|||
bool s2n_valid;
|
||||
|
||||
unsigned cap;
|
||||
static int DTMF_row[];
|
||||
static int DTMF_col[];
|
||||
|
||||
public:
|
||||
modem();
|
||||
virtual ~modem(){};
|
||||
|
@ -177,6 +180,11 @@ public:
|
|||
void cwid_sendtext (const std::string& s);
|
||||
void cwid();
|
||||
|
||||
// for DTMF transmission
|
||||
void DTMF_silence(int);
|
||||
void DTMF_two_tones(int);
|
||||
void DTMF_send();
|
||||
|
||||
// for noise tests
|
||||
private:
|
||||
void add_noise(double *, int);
|
||||
|
|
|
@ -158,6 +158,7 @@ void loadBrowser(Fl_Widget *widget) {
|
|||
w->add(_("<TEXT>\tvideo text"));
|
||||
w->add(_("<TXRSID:on|off|t>\tTx RSID on,off,toggle"));
|
||||
w->add(_("<RXRSID:on|off|t>\tRx RSID on,off,toggle"));
|
||||
w->add(_("<DTMF:digits>\tTx digits string"));
|
||||
|
||||
w->add(LINE_SEP);
|
||||
w->add(_("<POST:+/-nn.n>\tCW QSK post-timing"));
|
||||
|
|
|
@ -141,6 +141,7 @@ void pAFC(string &, size_t &);
|
|||
void pLOCK(string &, size_t &);
|
||||
void pRX_RSID(string &, size_t &);
|
||||
void pTX_RSID(string &, size_t &);
|
||||
void pDTMF(string &, size_t &);
|
||||
|
||||
#ifdef __WIN32__
|
||||
void pTALK(string &, size_t &);
|
||||
|
@ -227,6 +228,7 @@ MTAGS mtags[] = {
|
|||
{"<LOCK:", pLOCK},
|
||||
{"<RXRSID:", pRX_RSID},
|
||||
{"<TXRSID:", pTX_RSID},
|
||||
{"<DTMF:", pDTMF},
|
||||
{"<SRCHUP>", pSRCHUP},
|
||||
{"<SRCHDN>", pSRCHDN},
|
||||
{"<GOHOME>", pGOHOME},
|
||||
|
@ -627,6 +629,13 @@ void pCWID(string &s, size_t &i)
|
|||
s.replace( i, 6, "");
|
||||
}
|
||||
|
||||
void pDTMF(string &s, size_t &i)
|
||||
{
|
||||
size_t endbracket = s.find('>',i);
|
||||
progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6);
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
void pRX(string &s, size_t &i)
|
||||
{
|
||||
s.replace (i, 4, "^r");
|
||||
|
|
|
@ -971,3 +971,89 @@ mfntchr idch2[] = {
|
|||
};
|
||||
|
||||
|
||||
//======================================================================
|
||||
// DTMF tone transmit
|
||||
//======================================================================
|
||||
int modem::DTMF_row[] = {
|
||||
941, 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 697, 770, 852, 941};
|
||||
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D
|
||||
|
||||
int modem::DTMF_col[] = {
|
||||
1336, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1336, 1477, 1209, 1477, 1633, 1633, 1633, 1633};
|
||||
// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, *, #, A, B, C, D
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// transmit silence for specified time duration
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void modem::DTMF_silence(int duration)
|
||||
{
|
||||
double sr = active_modem->get_samplerate();
|
||||
int length = duration * sr / 1000;
|
||||
memset(outbuf, 0, length * sizeof(*outbuf));
|
||||
active_modem->ModulateXmtr(outbuf, length);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// transmit DTMF tones for specific time interval
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void modem::DTMF_two_tones(int rc)
|
||||
{
|
||||
if (rc < 0 || rc > 15) return;
|
||||
double sr = active_modem->get_samplerate();
|
||||
double phaseincr = 2.0 * M_PI * DTMF_row[rc] / sr;
|
||||
double phase = 0;
|
||||
printf("%d %d\n", DTMF_row[rc], DTMF_col[rc]);
|
||||
int length = 50 * sr / 1000;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
outbuf[i] = 0.5 * sin(phase);
|
||||
phase += phaseincr;
|
||||
}
|
||||
|
||||
phaseincr = 2.0 * M_PI * DTMF_col[rc] / sr;
|
||||
phase = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
outbuf[i] += 0.5 * sin(phase);
|
||||
phase += phaseincr;
|
||||
}
|
||||
for (int i = 0; i < RT; i++) {
|
||||
outbuf[i] *= cwid_keyshape[i];
|
||||
outbuf[length - 1 - i] *= cwid_keyshape[i];
|
||||
}
|
||||
|
||||
active_modem->ModulateXmtr(outbuf, length);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// transmit the string contained in progdefaults.DTMFstr and output as
|
||||
// dtmf valid characters, 0-9, *, #, A-D
|
||||
// each pair of tones is separated by 50ms silence
|
||||
// 500 msec silence for ' ', ',' or '-'
|
||||
// 50 msec silence for invalid characters
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void modem::DTMF_send()
|
||||
{
|
||||
if (progdefaults.DTMFstr.empty()) return;
|
||||
|
||||
int c = 0;
|
||||
|
||||
RT = (int) (samplerate * 4 / 1000.0); // 4 msec rise/fall time
|
||||
cwid_makeshape();
|
||||
|
||||
for(size_t i = 0; i < progdefaults.DTMFstr.length(); i++) {
|
||||
c = progdefaults.DTMFstr[i];
|
||||
if (c == ' ' || c == ',' || c == '-') DTMF_silence(50);
|
||||
else if (c >= '0' && c <= '9') DTMF_two_tones(c - '0');
|
||||
else if (c == '*') DTMF_two_tones(10);
|
||||
else if (c == '#') DTMF_two_tones(11);
|
||||
else if (c >= 'A' && c <= 'D') DTMF_two_tones(12 + c - 'A');
|
||||
else if (c >= 'a' && c <= 'd') DTMF_two_tones(12 + c - 'a');
|
||||
DTMF_silence(50);
|
||||
}
|
||||
progdefaults.DTMFstr.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -312,6 +312,8 @@ void trx_trx_transmit_loop()
|
|||
if (progdefaults.TransmitRSid)
|
||||
ReedSolomon->send(true);
|
||||
|
||||
active_modem->DTMF_send();
|
||||
|
||||
while (trx_state == STATE_TX) {
|
||||
try {
|
||||
if (active_modem->tx_process() < 0)
|
||||
|
|
Ładowanie…
Reference in New Issue