dl-fldigi/src/blank/blank.cxx

230 wiersze
4.6 KiB
C++

// ----------------------------------------------------------------------------
// blank.cxx -- BLANK modem
//
// Copyright (C) 2006
// Dave Freese, W1HKJ
//
// This file is part of fldigi. Adapted from code contained in gMFSK source code
// distribution.
// gMFSK Copyright (C) 2001, 2002, 2003
// Tomi Manninen (oh2bns@sral.fi)
//
// Fldigi 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 3 of the License, or
// (at your option) any later version.
//
// Fldigi 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 fldigi. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include <config.h>
#include <stdlib.h>
#include <iostream>
#include "BLANK.h"
#include "ascii.h"
char BLANKmsg[80];
void BLANK::tx_init(SoundBase *sc)
{
scard = sc;
}
void BLANK::rx_init()
{
put_MODEstatus(mode);
}
void BLANK::init()
{
modem::init();
rx_init();
digiscope->mode(Digiscope::SCOPE);
}
BLANK::~BLANK()
{
delete bandpass;
delete hilbert;
delete lowpass;
delete sliding;
delete [] scope_data;
delete [] out_buf;
delete [] in_buf;
}
BLANK::BLANK(trx_mode BLANK_mode) : modem()
{
double cf, flo, fhi;
mode = BLANK_mode;
symlen = SYMLEN;
bandwidth = BLANK_BW;
samplerate = BLANKSampleRate;
flo = LP_F1 / corrRxSampleRate();
lowpass = new C_FIR_filter();
lowpass->init_lowpass (LP_FIRLEN, LP_DEC, flo );
flo = BP_F1 / corrRxSampleRate();
fhi = BP_F2 / corrRxSampleRate();
bandpass = new C_FIR_filter();
bandpass->init_bandpass (BP_FIRLEN, BP_DEC, flo, fhi );
hilbert = new C_FIR_filter();
hilbert->init_hilbert(37, 1);
sliding = new sfft (SL_LEN, SL_F1, SL_F2); // all integer values
scope_data = new double [SCOPE_DATA_LEN];
out_buf = new double [SYMLEN];
in_buf = new double [BUFLEN];
// init();
}
//=====================================================================
// receive processing
//=====================================================================
void BLANK::recvchar(int c)
{
if (c == -1)
return;
put_rx_char(c);
}
void BLANK::decodesymbol(unsigned char symbol)
{
}
complex BLANK::mixer(complex in, double f)
{
complex z;
// f may have to be modified
z = in * complex( cos(phaseacc), sin(phaseacc) );
phaseacc -= TWOPI * f / corrRxSampleRate();
if (phaseacc < 0) phaseacc += TWOPI;
return z;
}
void BLANK::update_syncscope()
{
int j;
memset(scopedata, 0, 2 * SCOPE_DATA_LEN);
if (!squelchon || metric >= squelch)
for (int i = 0; i < 2 * symlen; i++) {
// j = (i + pipeptr) % (2 * symlen);
// scopedata[i] = (pipe[j].vector[prev1symbol]).mag();
}
set_scope(scope_data, SCOPE_DATA_LEN);
}
void BLANK::afc()
{
complex z;
double x;
if (metric < squelch)
return;
// adjust "frequency" iaw with afc processing
}
int BLANK::rx_process(const double *buf, int len)
{
complex z;
int i;
while (len-- > 0) {
// create analytic signal...
z.re = z.im = *buf++;
hbfilt->run ( z, z );
// shift in frequency to the base freq of 1000 hz
z = mixer(z, frequency);
// bandpass filter around the shifted center frequency
// with required bandwidth
bandpass->run ( z, z );
// binsfft->run(z) copies frequencies of interest
complex dummy ;
sliding->run (z, &dummy, 0 );
// etc
decodesymbol();
update_syncscope();
afc();
}
return 0;
}
//=====================================================================
// transmit processing
//=====================================================================
void BLANK::sendchar(unsigned char c)
{
// need to generate the outbuf
ModulateXmtr(outbuf, symlen);
put_echo_char(c);
}
void sendidle() {
}
int BLANK::tx_process()
{
int xmtbyte;
switch (txstate) {
case TX_STATE_PREAMBLE:
for (int i = 0; i < 32; i++)
sendbit(0);
txstate = TX_STATE_START;
break;
case TX_STATE_START:
sendchar('\r');
sendchar(2); // STX
sendchar('\r');
txstate = TX_STATE_DATA;
break;
case TX_STATE_DATA:
xmtbyte = get_tx_char();
if (xmtbyte == GET_TX_CHAR_NODATA)
sendidle();
else if ( xmtbyte == GET_TX_CHAR_ETX || stopflag)
txstate = TX_STATE_FLUSH;
else
sendchar(xmtbyte);
break;
case TX_STATE_FLUSH:
sendchar('\r');
sendchar(4); // EOT
sendchar('\r');
flushtx();
stopflag = false;
// tell trx process that xmt is done
return -1;
default:
break;
}
return 0;
}