Asterisk - The Open Source Telephony Project GIT-master-f36a736
Macros | Functions | Variables
fskmodem_int.c File Reference

FSK Modulator/Demodulator. More...

#include "asterisk.h"
#include "asterisk/fskmodem.h"
Include dependency graph for fskmodem_int.c:

Go to the source code of this file.

Macros

#define BWLIST   {75,800}
 
#define FLIST   {1400,1800,1200,2200,1300,2100}
 
#define IGET_SAMPLE   iget_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

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. More...
 
int fskmodem_init (fsk_data *fskd)
 
static int get_bit_raw (fsk_data *fskd, short *buffer, int *len)
 
static int ibpdfilter (struct filter_struct *fs, int in)
 
static int ibpfilter (struct filter_struct *fs, int in)
 
static int idemodulator (fsk_data *fskd, int *retval, int x)
 
static int iget_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]. More...
 
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]. More...
 

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_int.c.

Macro Definition Documentation

◆ BWLIST

#define BWLIST   {75,800}

Definition at line 40 of file fskmodem_int.c.

◆ FLIST

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

Definition at line 42 of file fskmodem_int.c.

◆ IGET_SAMPLE

#define IGET_SAMPLE   iget_sample(&buffer, len)

Definition at line 58 of file fskmodem_int.c.

◆ NBW

#define NBW   2

Definition at line 39 of file fskmodem_int.c.

◆ NF

#define NF   6

Definition at line 41 of file fskmodem_int.c.

◆ STATE_GET_BYTE

#define STATE_GET_BYTE   3

Definition at line 47 of file fskmodem_int.c.

◆ STATE_SEARCH_STARTBIT

#define STATE_SEARCH_STARTBIT   0

Definition at line 44 of file fskmodem_int.c.

◆ STATE_SEARCH_STARTBIT2

#define STATE_SEARCH_STARTBIT2   1

Definition at line 45 of file fskmodem_int.c.

◆ STATE_SEARCH_STARTBIT3

#define STATE_SEARCH_STARTBIT3   2

Definition at line 46 of file fskmodem_int.c.

Function Documentation

◆ 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 222 of file fskmodem_int.c.

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

References a, demodulator(), get_bit_raw(), GET_SAMPLE, idemodulator(), IGET_SAMPLE, fsk_data::instop, fsk_data::ispb, len(), fsk_data::nbit, fsk_data::nstop, fsk_data::parity, fsk_data::spb, fsk_data::state, STATE_GET_BYTE, STATE_SEARCH_STARTBIT, STATE_SEARCH_STARTBIT2, STATE_SEARCH_STARTBIT3, fsk_data::x1, fsk_data::x2, fsk_data::xi1, and fsk_data::xi2.

Referenced by callerid_feed(), callerid_feed_jp(), and tdd_feed().

◆ fskmodem_init()

int fskmodem_init ( fsk_data fskd)

Definition at line 195 of file fskmodem_int.c.

196{
197 int i;
198
199 fskd->space_filter.ip = 0;
200 fskd->mark_filter.ip = 0;
201 fskd->demod_filter.ip = 0;
202
203 for ( i = 0 ; i < 7 ; i++ ) {
204 fskd->space_filter.icoefs[i] =
205 coef_in[fskd->f_space_idx][fskd->bw][i] * 256;
206 fskd->space_filter.ixv[i] = 0;;
207 fskd->space_filter.iyv[i] = 0;;
208
209 fskd->mark_filter.icoefs[i] =
210 coef_in[fskd->f_mark_idx][fskd->bw][i] * 256;
211 fskd->mark_filter.ixv[i] = 0;;
212 fskd->mark_filter.iyv[i] = 0;;
213
214 fskd->demod_filter.icoefs[i] =
215 coef_out[fskd->bw][i] * 1024;
216 fskd->demod_filter.ixv[i] = 0;;
217 fskd->demod_filter.iyv[i] = 0;;
218 }
219 return 0;
220}
static double coef_in[NF][NBW][8]
Coefficients for input filters Coefficients table, generated by program "mkfilter" mkfilter is part o...
Definition: fskmodem_int.c:66
static double coef_out[NBW][8]
Coefficients for output filter Coefficients table, generated by program "mkfilter" Format: coef[IDX_B...
Definition: fskmodem_int.c:88
struct filter_struct demod_filter
Definition: fskmodem_int.h:65
struct filter_struct space_filter
Definition: fskmodem_int.h:64
int f_mark_idx
struct filter_struct mark_filter
Definition: fskmodem_int.h:63
int f_space_idx

References fsk_data::bw, coef_in, coef_out, fsk_data::demod_filter, fsk_data::f_mark_idx, fsk_data::f_space_idx, filter_struct::icoefs, filter_struct::ip, filter_struct::ixv, filter_struct::iyv, fsk_data::mark_filter, and fsk_data::space_filter.

Referenced by callerid_new(), and tdd_new().

◆ get_bit_raw()

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

Definition at line 165 of file fskmodem_int.c.

166{
167 /* This function implements a DPLL to synchronize with the bits */
168 int f;
169
170 int ix;
171 /* PLL coeffs are set up in callerid_new */
172 for (f = 0;;) {
173 if (idemodulator(fskd, &ix, IGET_SAMPLE)) return(-1);
174 if ((ix * fskd->xi0) < 0) { /* Transicion */
175 if (!f) {
176 if (fskd->icont < (fskd->pllispb2)) {
177 fskd->icont += fskd->pllids;
178 } else {
179 fskd->icont -= fskd->pllids;
180 }
181 f = 1;
182 }
183 }
184 fskd->xi0 = ix;
185 fskd->icont += 32;
186 if (fskd->icont > fskd->pllispb) {
187 fskd->icont -= fskd->pllispb;
188 break;
189 }
190 }
191 f = (ix > 0) ? 0x80 : 0;
192 return f;
193}
int pllispb2
Definition: fskmodem_int.h:61
int pllispb
Definition: fskmodem_int.h:59
int pllids
Definition: fskmodem_int.h:60

References fsk_data::icont, idemodulator(), IGET_SAMPLE, fsk_data::pllids, fsk_data::pllispb, fsk_data::pllispb2, and fsk_data::xi0.

Referenced by fsk_serial().

◆ ibpdfilter()

static int ibpdfilter ( struct filter_struct fs,
int  in 
)
inlinestatic

Integer Pass Band demodulator filter

Definition at line 95 of file fskmodem_int.c.

96{
97 int i,j;
98 int s;
99 int64_t s_interim;
100
101 /* integer filter */
102 s = in * fs->icoefs[0];
103 fs->ixv[(fs->ip + 6) & 7] = s;
104
105 s = (fs->ixv[fs->ip] + fs->ixv[(fs->ip + 6) & 7]) +
106 6 * (fs->ixv[(fs->ip + 1) & 7] + fs->ixv[(fs->ip + 5) & 7]) +
107 15 * (fs->ixv[(fs->ip + 2) & 7] + fs->ixv[(fs->ip + 4) & 7]) +
108 20 * fs->ixv[(fs->ip + 3) & 7];
109
110 for (i = 1, j = fs->ip; i < 7; i++, j++) {
111 /* Promote operation to 64 bit to prevent overflow that occurred in 32 bit) */
112 s_interim = (int64_t)(fs->iyv[j & 7]) *
113 (int64_t)(fs->icoefs[i]) /
114 (int64_t)(1024);
115 s += (int) s_interim;
116 }
117 fs->iyv[j & 7] = s;
118 fs->ip++;
119 fs->ip &= 7;
120 return s;
121}
FILE * in
Definition: utils/frame.c:33

References filter_struct::icoefs, in, filter_struct::ip, filter_struct::ixv, and filter_struct::iyv.

Referenced by idemodulator().

◆ ibpfilter()

static int ibpfilter ( struct filter_struct fs,
int  in 
)
inlinestatic

Integer Band Pass filter

Definition at line 124 of file fskmodem_int.c.

125{
126 int i, j;
127 int s;
128 int64_t s_interim;
129
130 /* integer filter */
131 s = in * fs->icoefs[0] / 256;
132 fs->ixv[(fs->ip + 6) & 7] = s;
133
134 s = (fs->ixv[(fs->ip + 6) & 7] - fs->ixv[fs->ip])
135 + 3 * (fs->ixv[(fs->ip + 2) & 7] - fs->ixv[(fs->ip + 4) & 7]);
136
137 for (i = 1, j = fs->ip; i < 7; i++, j++) {
138 s_interim = (int64_t)(fs->iyv[j & 7]) *
139 (int64_t)(fs->icoefs[i]) /
140 (int64_t)(256);
141 s += (int) s_interim;
142 }
143 fs->iyv[j & 7] = s;
144 fs->ip++;
145 fs->ip &= 7;
146 return s;
147}

References filter_struct::icoefs, in, filter_struct::ip, filter_struct::ixv, and filter_struct::iyv.

Referenced by idemodulator().

◆ idemodulator()

static int idemodulator ( fsk_data fskd,
int *  retval,
int  x 
)
inlinestatic

Definition at line 149 of file fskmodem_int.c.

150{
151 int is, im, id;
152 int ilin2;
153
154 is = ibpfilter(&fskd->space_filter, x);
155 im = ibpfilter(&fskd->mark_filter, x);
156
157 ilin2 = ((im * im) - (is * is)) / (256 * 256);
158
159 id = ibpdfilter(&fskd->demod_filter, ilin2);
160
161 *retval = id;
162 return 0;
163}
enum queue_result id
Definition: app_queue.c:1667
static int ibpfilter(struct filter_struct *fs, int in)
Definition: fskmodem_int.c:124
static int ibpdfilter(struct filter_struct *fs, int in)
Definition: fskmodem_int.c:95
static ENTRY retval
Definition: hsearch.c:50

References fsk_data::demod_filter, ibpdfilter(), ibpfilter(), id, fsk_data::mark_filter, retval, and fsk_data::space_filter.

Referenced by fsk_serial(), and get_bit_raw().

◆ iget_sample()

static int iget_sample ( short **  buffer,
int *  len 
)
inlinestatic

Definition at line 49 of file fskmodem_int.c.

50{
51 int retval;
52 retval = (int) **buffer;
53 (*buffer)++;
54 (*len)--;
55 return retval;
56}

References retval.

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 66 of file fskmodem_int.c.

Referenced by fskmodem_init().

◆ 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 88 of file fskmodem_int.c.

Referenced by fskmodem_init().