Asterisk - The Open Source Telephony Project GIT-master-773870a
Loading...
Searching...
No Matches
Macros | Functions | Variables
fskmodem_float.c File Reference

FSK Modulator/Demodulator. More...

#include "asterisk.h"
#include <stdio.h>
#include "asterisk/fskmodem.h"
Include dependency graph for fskmodem_float.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define BWLIST   {75,800}
 
#define FLIST   {1400,1800,1200,2200,1300,2100}
 
#define GET_SAMPLE   get_sample(&buffer, len)
 
#define NBW   2
 
#define NF   6
 
#define STATE_GET_BYTE   3
 
#define STATE_SEARCH_STARTBIT   0
 
#define STATE_SEARCH_STARTBIT2   1
 
#define STATE_SEARCH_STARTBIT3   2
 

Functions

static int demodulator (fsk_data *fskd, float *retval, float x)
 
static float filterL (fsk_data *fskd, float in)
 
static float filterM (fsk_data *fskd, float in)
 
static float filterS (fsk_data *fskd, float in)
 
int fsk_serial (fsk_data *fskd, short *buffer, int *len, int *outbyte)
 Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the number of bytes in the buffer. len will be overwritten with the number of bytes left that were not consumed.
 
static int get_bit_raw (fsk_data *fskd, short *buffer, int *len)
 
static float get_sample (short **buffer, int *len)
 

Variables

static double coef_in [NF][NBW][8]
 Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part of the zapatatelephony.org distribution Format: coef[IDX_FREC][IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].
 
static double coef_out [NBW][8]
 Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].
 

Detailed Description

FSK Modulator/Demodulator.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file fskmodem_float.c.

Macro Definition Documentation

◆ BWLIST

#define BWLIST   {75,800}

Definition at line 42 of file fskmodem_float.c.

◆ FLIST

#define FLIST   {1400,1800,1200,2200,1300,2100}

Definition at line 44 of file fskmodem_float.c.

◆ GET_SAMPLE

#define GET_SAMPLE   get_sample(&buffer, len)

Definition at line 60 of file fskmodem_float.c.

◆ NBW

#define NBW   2

Definition at line 41 of file fskmodem_float.c.

◆ NF

#define NF   6

Definition at line 43 of file fskmodem_float.c.

◆ STATE_GET_BYTE

#define STATE_GET_BYTE   3

Definition at line 49 of file fskmodem_float.c.

◆ STATE_SEARCH_STARTBIT

#define STATE_SEARCH_STARTBIT   0

Definition at line 46 of file fskmodem_float.c.

◆ STATE_SEARCH_STARTBIT2

#define STATE_SEARCH_STARTBIT2   1

Definition at line 47 of file fskmodem_float.c.

◆ STATE_SEARCH_STARTBIT3

#define STATE_SEARCH_STARTBIT3   2

Definition at line 48 of file fskmodem_float.c.

Function Documentation

◆ demodulator()

static int demodulator ( fsk_data fskd,
float *  retval,
float  x 
)
inlinestatic

Definition at line 169 of file fskmodem_float.c.

170{
171 float xS,xM;
172
173 fskd->cola_in[fskd->pcola] = x;
174
175 xS = filterS(fskd,x);
176 xM = filterM(fskd,x);
177
178 fskd->cola_filter[fskd->pcola] = xM-xS;
179
180 x = filterL(fskd,xM*xM - xS*xS);
181
182 fskd->cola_demod[fskd->pcola++] = x;
183 fskd->pcola &= (NCOLA-1);
184
185 *retval = x;
186 return 0;
187}
static float filterM(fsk_data *fskd, float in)
static float filterL(fsk_data *fskd, float in)
static float filterS(fsk_data *fskd, float in)
#define NCOLA
float cola_in[NCOLA]
float cola_filter[NCOLA]
float cola_demod[NCOLA]

References fsk_data::cola_demod, fsk_data::cola_filter, fsk_data::cola_in, filterL(), filterM(), filterS(), NCOLA, and fsk_data::pcola.

Referenced by fsk_serial(), and get_bit_raw().

◆ filterL()

static float filterL ( fsk_data fskd,
float  in 
)
inlinestatic

Low-pass filter for demodulated data

Definition at line 147 of file fskmodem_float.c.

148{
149 int i, j;
150 double s;
151 double *pc;
152
153 pc = &coef_out[fskd->bw][0];
154 fskd->flxv[(fskd->flp + 6) & 7] = in * (*pc++);
155
156 s = (fskd->flxv[fskd->flp] + fskd->flxv[(fskd->flp+6)&7]) +
157 6 * (fskd->flxv[(fskd->flp+1)&7] + fskd->flxv[(fskd->flp+5)&7]) +
158 15 * (fskd->flxv[(fskd->flp+2)&7] + fskd->flxv[(fskd->flp+4)&7]) +
159 20 * fskd->flxv[(fskd->flp+3)&7];
160
161 for (i = 0,j = fskd->flp;i<6;i++,j++)
162 s += fskd->flyv[j&7]*(*pc++);
163 fskd->flyv[j&7] = s;
164 fskd->flp++;
165 fskd->flp &= 7;
166 return s;
167}
static double coef_out[NBW][8]
Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_B...
double flxv[8]
double flyv[8]
FILE * in
Definition utils/frame.c:33

References fsk_data::bw, coef_out, fsk_data::flp, fsk_data::flxv, fsk_data::flyv, and in.

Referenced by demodulator().

◆ filterM()

static float filterM ( fsk_data fskd,
float  in 
)
inlinestatic

Band-pass filter for MARK frequency

Definition at line 109 of file fskmodem_float.c.

110{
111 int i, j;
112 double s;
113 double *pc;
114
115 pc = &coef_in[fskd->f_mark_idx][fskd->bw][0];
116 fskd->fmxv[(fskd->fmp+6)&7] = in*(*pc++);
117
118 s = (fskd->fmxv[(fskd->fmp + 6) & 7] - fskd->fmxv[fskd->fmp]) + 3 * (fskd->fmxv[(fskd->fmp + 2) & 7] - fskd->fmxv[(fskd->fmp + 4) & 7]);
119 for (i = 0, j = fskd->fmp; i < 6; i++, j++)
120 s += fskd->fmyv[j&7]*(*pc++);
121 fskd->fmyv[j&7] = s;
122 fskd->fmp++;
123 fskd->fmp &= 7;
124 return s;
125}
static double coef_in[NF][NBW][8]
Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part o...
double fmyv[8]
double fmxv[8]

References fsk_data::bw, coef_in, fsk_data::f_mark_idx, fsk_data::fmp, fsk_data::fmxv, fsk_data::fmyv, and in.

Referenced by demodulator().

◆ filterS()

static float filterS ( fsk_data fskd,
float  in 
)
inlinestatic

Band-pass filter for SPACE frequency

Definition at line 128 of file fskmodem_float.c.

129{
130 int i, j;
131 double s;
132 double *pc;
133
134 pc = &coef_in[fskd->f_space_idx][fskd->bw][0];
135 fskd->fsxv[(fskd->fsp+6)&7] = in*(*pc++);
136
137 s = (fskd->fsxv[(fskd->fsp + 6) & 7] - fskd->fsxv[fskd->fsp]) + 3 * (fskd->fsxv[(fskd->fsp + 2) & 7] - fskd->fsxv[(fskd->fsp + 4) & 7]);
138 for (i = 0, j = fskd->fsp; i < 6; i++, j++)
139 s += fskd->fsyv[j&7]*(*pc++);
140 fskd->fsyv[j&7] = s;
141 fskd->fsp++;
142 fskd->fsp &= 7;
143 return s;
144}
double fsyv[8]
double fsxv[8]

References fsk_data::bw, coef_in, fsk_data::f_space_idx, fsk_data::fsp, fsk_data::fsxv, fsk_data::fsyv, and in.

Referenced by demodulator().

◆ fsk_serial()

int fsk_serial ( fsk_data fskd,
short *  buffer,
int *  len,
int *  outbyte 
)

Retrieve a serial byte into outbyte. Buffer is a pointer into a series of shorts and len records the number of bytes in the buffer. len will be overwritten with the number of bytes left that were not consumed.

Return values
0Still looking for something...
1An output byte was received and stored in outbyte
-1An error occured in the transmission He must be called with at least 80 bytes of buffer.

Definition at line 224 of file fskmodem_float.c.

225{
226 int a;
227 int i,j,n1,r;
228 int olen;
229
230 switch (fskd->state) {
231 /* Pick up where we left off */
233 goto search_startbit2;
235 goto search_startbit3;
236 case STATE_GET_BYTE:
237 goto getbyte;
238 }
239 /* We await for start bit */
240 do {
241 /* this was jesus's nice, reasonable, working (at least with RTTY) code
242 to look for the beginning of the start bit. Unfortunately, since TTY/TDD's
243 just start sending a start bit with nothing preceding it at the beginning
244 of a transmission (what a LOSING design), we cant do it this elegantly */
245 /*
246 if (demodulator(zap,&x1)) return(-1);
247 for (;;) {
248 if (demodulator(zap,&x2)) return(-1);
249 if (x1>0 && x2<0) break;
250 x1 = x2;
251 }
252 */
253 /* this is now the imprecise, losing, but functional code to detect the
254 beginning of a start bit in the TDD sceanario. It just looks for sufficient
255 level to maybe, perhaps, guess, maybe that its maybe the beginning of
256 a start bit, perhaps. This whole thing stinks! */
257 if (demodulator(fskd, &fskd->x1, GET_SAMPLE))
258 return -1;
259 for (;;) {
260search_startbit2:
261 if (*len <= 0) {
263 return 0;
264 }
265 if (demodulator(fskd, &fskd->x2, GET_SAMPLE))
266 return(-1);
267#if 0
268 printf("x2 = %5.5f ", fskd->x2);
269#endif
270 if (fskd->x2 < -0.5)
271 break;
272 }
273search_startbit3:
274 /* We await for 0.5 bits before using DPLL */
275 i = fskd->spb/2;
276 if (*len < i) {
278 return 0;
279 }
280 for (; i>0; i--) {
281 if (demodulator(fskd, &fskd->x1, GET_SAMPLE))
282 return(-1);
283#if 0
284 printf("x1 = %5.5f ", fskd->x1);
285#endif
286 }
287
288 /* x1 must be negative (start bit confirmation) */
289
290 } while (fskd->x1 > 0);
291 fskd->state = STATE_GET_BYTE;
292
293getbyte:
294
295 /* Need at least 80 samples (for 1200) or
296 1320 (for 45.5) to be sure we'll have a byte */
297 if (fskd->nbit < 8) {
298 if (*len < 1320)
299 return 0;
300 } else {
301 if (*len < 80)
302 return 0;
303 }
304 /* Now we read the data bits */
305 j = fskd->nbit;
306 for (a = n1 = 0; j; j--) {
307 olen = *len;
308 i = get_bit_raw(fskd, buffer, len);
309 buffer += (olen - *len);
310 if (i == -1)
311 return(-1);
312 if (i)
313 n1++;
314 a >>= 1;
315 a |= i;
316 }
317 j = 8-fskd->nbit;
318 a >>= j;
319
320 /* We read parity bit (if exists) and check parity */
321 if (fskd->parity) {
322 olen = *len;
323 i = get_bit_raw(fskd, buffer, len);
324 buffer += (olen - *len);
325 if (i == -1)
326 return(-1);
327 if (i)
328 n1++;
329 if (fskd->parity == 1) { /* parity=1 (even) */
330 if (n1&1)
331 a |= 0x100; /* error */
332 } else { /* parity=2 (odd) */
333 if (!(n1&1))
334 a |= 0x100; /* error */
335 }
336 }
337
338 /* We read STOP bits. All of them must be 1 */
339
340 for (j = fskd->nstop;j;j--) {
341 r = get_bit_raw(fskd, buffer, len);
342 if (r == -1)
343 return(-1);
344 if (!r)
345 a |= 0x200;
346 }
347
348 /* And finally we return */
349 /* Bit 8 : Parity error */
350 /* Bit 9 : Framing error*/
351
352 *outbyte = a;
354 return 1;
355}
static int get_bit_raw(fsk_data *fskd, short *buffer, int *len)
static int demodulator(fsk_data *fskd, float *retval, float x)
#define STATE_SEARCH_STARTBIT2
#define STATE_SEARCH_STARTBIT
#define STATE_GET_BYTE
#define GET_SAMPLE
#define STATE_SEARCH_STARTBIT3
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct test_val a

◆ get_bit_raw()

static int get_bit_raw ( fsk_data fskd,
short *  buffer,
int *  len 
)
static

Definition at line 189 of file fskmodem_float.c.

190{
191 /* This function implements a DPLL to synchronize with the bits */
192 float x,spb,spb2,ds;
193 int f;
194
195 spb = fskd->spb;
196 if (fskd->spb == 7)
197 spb = 8000.0 / 1200.0;
198 ds = spb/32.;
199 spb2 = spb/2.;
200
201 for (f = 0;;) {
202 if (demodulator(fskd, &x, GET_SAMPLE))
203 return -1;
204 if ((x * fskd->x0) < 0) { /* Transition */
205 if (!f) {
206 if (fskd->cont<(spb2))
207 fskd->cont += ds;
208 else
209 fskd->cont -= ds;
210 f = 1;
211 }
212 }
213 fskd->x0 = x;
214 fskd->cont += 1.;
215 if (fskd->cont > spb) {
216 fskd->cont -= spb;
217 break;
218 }
219 }
220 f = (x > 0) ? 0x80 : 0;
221 return f;
222}

References fsk_data::cont, demodulator(), GET_SAMPLE, fsk_data::spb, and fsk_data::x0.

Referenced by fsk_serial().

◆ get_sample()

static float get_sample ( short **  buffer,
int *  len 
)
inlinestatic

Definition at line 51 of file fskmodem_float.c.

52{
53 float retval;
54 retval = (float) **buffer / 256;
55 (*buffer)++;
56 (*len)--;
57 return retval;
58};

Variable Documentation

◆ coef_in

double coef_in[NF][NBW][8]
static

Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part of the zapatatelephony.org distribution Format: coef[IDX_FREC][IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].

Definition at line 69 of file fskmodem_float.c.

69 {
70 {
71 { 1.8229206611e-04,-7.8997325866e-01,2.2401819940e+00,-4.6751353581e+00,5.5080745712e+00,-5.0571565772e+00,2.6215820004e+00,0.0000000000e+00, },
72 { 9.8532175289e-02,-5.6297236492e-02,3.3146713415e-01,-9.2239200436e-01,1.4844365184e+00,-2.0183258642e+00,2.0074154497e+00,0.0000000000e+00, },
73 },
74 {
75 { 1.8229206610e-04,-7.8997325866e-01,7.7191410839e-01,-2.8075643964e+00,1.6948618347e+00,-3.0367273700e+00,9.0333559408e-01,0.0000000000e+00, },
76 { 9.8531161839e-02,-5.6297236492e-02,1.1421579050e-01,-4.8122536483e-01,4.0121072432e-01,-7.4834487567e-01,6.9170822332e-01,0.0000000000e+00, },
77 },
78 {
79 { 1.8229206611e-04,-7.8997325866e-01,2.9003821430e+00,-6.1082779024e+00,7.7169345751e+00,-6.6075999680e+00,3.3941838836e+00,0.0000000000e+00, },
80 { 9.8539686961e-02,-5.6297236492e-02,4.2915323820e-01,-1.2609358633e+00,2.2399213250e+00,-2.9928879142e+00,2.5990173742e+00,0.0000000000e+00, },
81 },
82 {
83 { 1.8229206610e-04,-7.8997325866e-01,-7.7191410839e-01,-2.8075643964e+00,-1.6948618347e+00,-3.0367273700e+00,-9.0333559408e-01,0.0000000000e+00, },
84 { 9.8531161839e-02,-5.6297236492e-02,-1.1421579050e-01,-4.8122536483e-01,-4.0121072432e-01,-7.4834487567e-01,-6.9170822332e-01,0.0000000000e+00, },
85 },
86 {
87 { 1.8229206611e-04,-7.8997325866e-01,2.5782298908e+00,-5.3629717478e+00,6.5890882172e+00,-5.8012914776e+00,3.0171839130e+00,0.0000000000e+00, },
88 { 9.8534230718e-02,-5.6297236492e-02,3.8148618075e-01,-1.0848760410e+00,1.8441165168e+00,-2.4860666655e+00,2.3103384142e+00,0.0000000000e+00, },
89 },
90 {
91 { 1.8229206610e-04,-7.8997325866e-01,-3.8715051001e-01,-2.6192408538e+00,-8.3977994034e-01,-2.8329897913e+00,-4.5306444352e-01,0.0000000000e+00, },
92 { 9.8531160936e-02,-5.6297236492e-02,-5.7284484199e-02,-4.3673866734e-01,-1.9564766257e-01,-6.2028156584e-01,-3.4692356122e-01,0.0000000000e+00, },
93 },
94};

Referenced by filterM(), and filterS().

◆ coef_out

double coef_out[NBW][8]
static
Initial value:
= {
{ 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00, },
{ 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00, },
}

Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_BW][IDX_COEF] IDX_COEF = 0 => 1/GAIN IDX_COEF = 1-6 => Coefficientes y[n].

Definition at line 102 of file fskmodem_float.c.

102 {
103 { 1.3868644653e-08,-6.3283665042e-01,4.0895057217e+00,-1.1020074592e+01,1.5850766191e+01,-1.2835109292e+01,5.5477477340e+00,0.0000000000e+00, },
104 { 3.1262119724e-03,-7.8390522307e-03,8.5209627801e-02,-4.0804129163e-01,1.1157139955e+00,-1.8767603680e+00,1.8916395224e+00,0.0000000000e+00, },
105};

Referenced by filterL().