1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * v22bis_tx.c - ITU V.22bis modem transmit part
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2004 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 2.1,
14 * as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: v22bis_tx.c,v 1.43 2008/07/02 14:48:26 steveu Exp $
26 */
27
28 /*! \file */
29
30 /* THIS IS A WORK IN PROGRESS - NOT YET FUNCTIONAL! */
31
32 #if defined(HAVE_CONFIG_H)
33 #include <config.h>
34 #endif
35
36 #include <stdio.h>
37 #include <inttypes.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include "floating_fudge.h"
41 #if defined(HAVE_TGMATH_H)
42 #include <tgmath.h>
43 #endif
44 #if defined(HAVE_MATH_H)
45 #include <math.h>
46 #endif
47
48 #include "spandsp/telephony.h"
49 #include "spandsp/logging.h"
50 #include "spandsp/complex.h"
51 #include "spandsp/vector_float.h"
52 #include "spandsp/complex_vector_float.h"
53 #include "spandsp/async.h"
54 #include "spandsp/dds.h"
55 #include "spandsp/power_meter.h"
56
57 #include "spandsp/v29rx.h"
58 #include "spandsp/v22bis.h"
59
60 #if defined(SPANDSP_USE_FIXED_POINT)
61 #include "v22bis_tx_fixed_rrc.h"
62 #else
63 #include "v22bis_tx_floating_rrc.h"
64 #endif
65
66 /* Quoting from the V.22bis spec.
67
68 6.3.1.1 Interworking at 2400 bit/s
69
70 6.3.1.1.1 Calling modem
71
72 a) On connection to line the calling modem shall be conditioned to receive signals
73 in the high channel at 1200 bit/s and transmit signals in the low channel at 1200 bit/s
74 in accordance with section 2.5.2.2. It shall apply an ON condition to circuit 107 in accordance
75 with Recommendation V.25. The modem shall initially remain silent.
76
77 b) After 155 +-10 ms of unscrambled binary 1 has been detected, the modem shall remain silent
78 for a further 456 +-10 ms then transmit an unscrambled repetitive double dibit pattern of 00
79 and 11 at 1200 bit/s for 100 +-3 ms. Following this signal the modem shall transmit scrambled
80 binary 1 at 1200 bit/s.
81
82 c) If the modem detects scrambled binary 1 in the high channel at 1200 bit/s for 270 +-40 ms,
83 the handshake shall continue in accordance with section 6.3.1.2.1 c) and d). However, if unscrambled
84 repetitive double dibit 00 and 11 at 1200 bit/s is detected in the high channel, then at the
85 end of receipt of this signal the modem shall apply an ON condition to circuit 112.
86
87 d) 600 +-10 ms after circuit 112 has been turned ON the modem shall begin transmitting scrambled
88 binary 1 at 2400 bit/s, and 450 +-10 ms after circuit 112 has been turned ON the receiver may
89 begin making 16-way decisions.
90
91 e) Following transmission of scrambled binary 1 at 2400 bit/s for 200 +-10 ms, circuit 106 shall
92 be conditioned to respond to circuit 105 and the modem shall be ready to transmit data at
93 2400 bit/s.
94
95 f) When 32 consecutive bits of scrambled binary 1 at 2400 bit/s have been detected in the high
96 channel the modem shall be ready to receive data at 2400 bit/s and shall apply an ON condition
97 to circuit 109.
98
99 6.3.1.1.2 Answering modem
100
101 a) On connection to line the answering modem shall be conditioned to transmit signals in the high
102 channel at 1200 bit/s in accordance with section 2.5.2.2 and receive signals in the low channel at
103 1200 bit/s. Following transmission of the answer sequence in accordance with Recommendation
104 V.25, the modem shall apply an ON condition to circuit 107 and then transmit unscrambled
105 binary 1 at 1200 bit/s.
106
107 b) If the modem detects scrambled binary 1 or 0 in the low channel at 1200 bit/s for 270 +-40 ms,
108 the handshake shall continue in accordance with section 6.3.1.2.2 b) and c). However, if unscrambled
109 repetitive double dibit 00 and 11 at 1200 bit/s is detected in the low channel, at the end of
110 receipt of this signal the modem shall apply an ON condition to circuit 112 and then transmit
111 an unscrambled repetitive double dibit pattern of 00 and 11 at 1200 bit/s for 100 +-3 ms.
112 Following these signals the modem shall transmit scrambled binary 1 at 1200 bit/s.
113
114 c) 600 +-10 ms after circuit 112 has been turned ON the modem shall begin transmitting scrambled
115 binary 1 at 2400 bit/s, and 450 +-10 ms after circuit 112 has been turned ON the receiver may
116 begin making 16-way decisions.
117
118 d) Following transmission of scrambled binary 1 at 2400 bit/s for 200 +-10 ms, circuit 106 shall
119 be conditioned to respond to circuit 105 and the modem shall be ready to transmit data at
120 2400 bit/s.
121
122 e) When 32 consecutive bits of scrambled binary 1 at 2400 bit/s have been detected in the low
123 channel the modem shall be ready to receive data at 2400 bit/s and shall apply an ON
124 condition to circuit 109.
125
126 6.3.1.2 Interworking at 1200 bit/s
127
128 The following handshake is identical to the Recommendation V.22 alternative A and B handshake.
129
130 6.3.1.2.1 Calling modem
131
132 a) On connection to line the calling modem shall be conditioned to receive signals in the high
133 channel at 1200 bit/s and transmit signals in the low channel at 1200 bit/s in accordance
134 with section 2.5.2.2. It shall apply an ON condition to circuit 107 in accordance with
135 Recommendation V.25. The modem shall initially remain silent.
136
137 b) After 155 +-10 ms of unscrambled binary 1 has been detected, the modem shall remain silent
138 for a further 456 +-10 ms then transmit scrambled binary 1 at 1200 bit/s (a preceding V.22 bis
139 signal, as shown in Figure 7/V.22 bis, would not affect the operation of a V.22 answer modem).
140
141 c) On detection of scrambled binary 1 in the high channel at 1200 bit/s for 270 +-40 ms the modem
142 shall be ready to receive data at 1200 bit/s and shall apply an ON condition to circuit 109 and
143 an OFF condition to circuit 112.
144
145 d) 765 +-10 ms after circuit 109 has been turned ON, circuit 106 shall be conditioned to respond
146 to circuit 105 and the modem shall be ready to transmit data at 1200 bit/s.
147
148 6.3.1.2.2 Answering modem
149
150 a) On connection to line the answering modem shall be conditioned to transmit signals in the high
151 channel at 1200 bit/s in accordance with section 2.5.2.2 and receive signals in the low channel at
152 1200 bit/s.
153
154 Following transmission of the answer sequence in accordance with V.25 the modem shall apply
155 an ON condition to circuit 107 and then transmit unscrambled binary 1 at 1200 bit/s.
156
157 b) On detection of scrambled binary 1 or 0 in the low channel at 1200 bit/s for 270 +-40 ms the
158 modem shall apply an OFF condition to circuit 112 and shall then transmit scrambled binary 1
159 at 1200 bit/s.
160
161 c) After scrambled binary 1 has been transmitted at 1200 bit/s for 765 +-10 ms the modem shall be
162 ready to transmit and receive data at 1200 bit/s, shall condition circuit 106 to respond to
163 circuit 105 and shall apply an ON condition to circuit 109.
164
165 Note - Manufacturers may wish to note that in certain countries, for national purposes, modems are
166 in service which emit an answering tone of 2225 Hz instead of unscrambled binary 1.
167
168
169 V.22bis to V.22bis
170 ------------------
171 Calling party
172 S1 scrambled 1's scrambled 1's data
173 at 1200bps at 2400bps
174 |---------------------------------------------------------|XXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXX|XXXXXXXXXXXXX
175 |<155+-10>|<456+-10>|<100+-3>| |<------600+-10------>|<---200+-10-->|
176 ^ | ^<----450+-100---->|[16 way decisions begin]
177 | | |
178 | v |
179 | |<------450+-100----->|[16 way decisions begin]
180 | |<----------600+-10-------->|
181 |<2150+-350>|<--3300+-700->|<75+-20>| |<100+-3>| |<---200+-10-->
182 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXX|XXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXX|XXXXXXXXXXXXX
183 silence 2100Hz unscrambled 1's S1 scrambled 1's scrambled 1's data
184 at 1200bps at 1200bps at 2400bps
185 Answering party
186
187 S1 = Unscrambled double dibit 00 and 11 at 1200bps
188 When the 2400bps section starts, both sides should look for 32 bits of continuous ones, as a test of integrity.
189
190
191
192
193 V.22 to V.22bis
194 ---------------
195 Calling party
196 scrambled 1's data
197 at 1200bps
198 |---------------------------------------------------------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
199 |<155+-10>|<456+-10>| |<270+-40>|<--------765+-10-------->|
200 ^ | ^
201 | | |
202 | | |
203 | | |
204 | v |
205 |<2150+-350>|<--3300+-700->|<75+-20>| |<270+-40>|<---------765+-10-------->|
206 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
207 silence 2100Hz unscrambled 1's scrambled 1's data
208 at 1200bps at 1200bps
209 Answering party
210
211 Both ends should accept unscrambled binary 1 or binary 0 as the preamble.
212
213
214
215
216 V.22bis to V.22
217 ---------------
218 Calling party
219 S1 scrambled 1's data
220 at 1200bps
221 |---------------------------------------------------------|XXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
222 |<155+-10>|<456+-10>|<100+-3>| |<-270+-40-><------765+-10------>|
223 ^ | ^
224 | | |
225 | v |
226 | |
227 | |
228 |<2150+-350>|<--3300+-700->|<75+-20>| |<-270+-40->|<------765+-10----->|
229 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
230 silence 2100Hz unscrambled 1's scrambled 1's data
231 at 1200bps at 1200bps
232 Answering party
233
234 Both ends should accept unscrambled binary 1 or binary 0 as the preamble.
235 */
236
237 #define ms_to_symbols(t) (((t)*600)/1000)
238
239 /* Segments of the training sequence */
240 enum
241 {
242 V22BIS_TRAINING_STAGE_NORMAL_OPERATION = 0,
243 V22BIS_TRAINING_STAGE_INITIAL_SILENCE,
244 V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES,
245 V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011,
246 V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200,
247 V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400,
248 V22BIS_TRAINING_STAGE_PARKED
249 };
250
251 static const int phase_steps[4] =
252 {
253 1, 0, 2, 3
254 };
255
256 const complexf_t v22bis_constellation[16] =
257 {
258 { 1.0f, 1.0f},
259 { 3.0f, 1.0f},
260 { 1.0f, 3.0f},
261 { 3.0f, 3.0f},
262 {-1.0f, 1.0f},
263 {-1.0f, 3.0f},
264 {-3.0f, 1.0f},
265 {-3.0f, 3.0f},
266 {-1.0f, -1.0f},
267 {-3.0f, -1.0f},
268 {-1.0f, -3.0f},
269 {-3.0f, -3.0f},
270 { 1.0f, -1.0f},
271 { 1.0f, -3.0f},
272 { 3.0f, -1.0f},
273 { 3.0f, -3.0f}
274 };
275
fake_get_bit(void * user_data)276 static int fake_get_bit(void *user_data)
277 {
278 return 1;
279 }
280 /*- End of function --------------------------------------------------------*/
281
scramble(v22bis_state_t * s,int bit)282 static __inline__ int scramble(v22bis_state_t *s, int bit)
283 {
284 int out_bit;
285
286 out_bit = (bit ^ (s->tx.scramble_reg >> 14) ^ (s->tx.scramble_reg >> 17)) & 1;
287 if (s->tx.scrambler_pattern_count >= 64)
288 {
289 out_bit ^= 1;
290 s->tx.scrambler_pattern_count = 0;
291 }
292 if (out_bit == 1)
293 s->tx.scrambler_pattern_count++;
294 else
295 s->tx.scrambler_pattern_count = 0;
296 s->tx.scramble_reg = (s->tx.scramble_reg << 1) | out_bit;
297 return out_bit;
298 }
299 /*- End of function --------------------------------------------------------*/
300
get_scrambled_bit(v22bis_state_t * s)301 static __inline__ int get_scrambled_bit(v22bis_state_t *s)
302 {
303 int bit;
304
305 if ((bit = s->tx.current_get_bit(s->user_data)) == PUTBIT_END_OF_DATA)
306 {
307 /* Fill out this symbol with ones, and prepare to send
308 the rest of the shutdown sequence. */
309 s->tx.current_get_bit = fake_get_bit;
310 s->tx.shutdown = 1;
311 bit = 1;
312 }
313 return scramble(s, bit);
314 }
315 /*- End of function --------------------------------------------------------*/
316
training_get(v22bis_state_t * s)317 static complexf_t training_get(v22bis_state_t *s)
318 {
319 complexf_t z;
320 int bits;
321
322 /* V.22bis training sequence */
323 switch (s->tx.training)
324 {
325 case V22BIS_TRAINING_STAGE_INITIAL_SILENCE:
326 /* Segment 1: silence */
327 s->tx.constellation_state = 0;
328 z = complex_setf(0.0f, 0.0f);
329 if (s->caller)
330 {
331 /* The caller just waits for a signal from the far end, which should be unscrambled ones */
332 if (s->detected_unscrambled_ones_or_zeros)
333 {
334 if (s->bit_rate == 2400)
335 {
336 /* Try to establish at 2400bps */
337 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting unscrambled 0011 at 1200 (S1)\n");
338 s->tx.training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011;
339 }
340 else
341 {
342 /* Only try at 1200bps */
343 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 1200 (A)\n");
344 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
345 }
346 s->tx.training_count = 0;
347 }
348 }
349 else
350 {
351 /* The answerer waits 75ms, then sends unscrambled ones */
352 if (++s->tx.training_count >= ms_to_symbols(75))
353 {
354 /* Inital 75ms of silence is over */
355 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting unscrambled ones at 1200\n");
356 s->tx.training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES;
357 s->tx.training_count = 0;
358 }
359 }
360 break;
361 case V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES:
362 /* Segment 2: Continuous unscrambled ones at 1200bps (i.e. reversals). */
363 /* Only the answering modem sends unscrambled ones. It is the first thing exchanged between the modems. */
364 s->tx.constellation_state = (s->tx.constellation_state + phase_steps[3]) & 3;
365 z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
366 if (s->bit_rate == 2400 && s->detected_unscrambled_0011_ending)
367 {
368 /* We are allowed to use 2400bps, and the far end is requesting 2400bps. Result: we are going to
369 work at 2400bps */
370 span_log(&s->logging, SPAN_LOG_FLOW, "+++ [2400] starting unscrambled 0011 at 1200 (S1)\n");
371 s->tx.training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011;
372 s->tx.training_count = 0;
373 break;
374 }
375 if (s->detected_scrambled_ones_or_zeros_at_1200bps)
376 {
377 /* We are going to work at 1200bps. */
378 span_log(&s->logging, SPAN_LOG_FLOW, "+++ [1200] starting scrambled ones at 1200 (B)\n");
379 s->bit_rate = 1200;
380 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
381 s->tx.training_count = 0;
382 break;
383 }
384 break;
385 case V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011:
386 /* Segment 3: Continuous unscrambled double dibit 00 11 at 1200bps. This is termed the S1 segment in
387 the V.22bis spec. It is only sent to request or accept 2400bps mode, and lasts 100+-3ms. After this
388 timed burst, we unconditionally change to sending scrambled ones at 1200bps. */
389 s->tx.constellation_state = (s->tx.constellation_state + phase_steps[(s->tx.training_count & 1) ? 3 : 0]) & 3;
390 span_log(&s->logging, SPAN_LOG_FLOW, "U0011 Tx 0x%02x\n", s->tx.constellation_state);
391 z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
392 if (++s->tx.training_count >= ms_to_symbols(100))
393 {
394 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 1200 (C)\n");
395 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
396 s->tx.training_count = 0;
397 }
398 break;
399 case V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200:
400 /* Segment 4: Scrambled ones at 1200bps. */
401 bits = scramble(s, 1);
402 bits = (bits << 1) | scramble(s, 1);
403 s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
404 z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
405 if (s->caller)
406 {
407 if (s->detected_unscrambled_0011_ending)
408 {
409 /* Continue for a further 600+-10ms */
410 if (++s->tx.training_count >= ms_to_symbols(600))
411 {
412 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (A)\n");
413 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
414 s->tx.training_count = 0;
415 }
416 }
417 else if (s->detected_scrambled_ones_or_zeros_at_1200bps)
418 {
419 if (s->bit_rate == 2400)
420 {
421 /* Continue for a further 756+-10ms */
422 if (++s->tx.training_count >= ms_to_symbols(756))
423 {
424 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (B)\n");
425 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
426 s->tx.training_count = 0;
427 }
428 }
429 else
430 {
431 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
432 s->tx.training = V22BIS_TRAINING_STAGE_NORMAL_OPERATION;
433 s->tx.training_count = 0;
434 s->tx.current_get_bit = s->get_bit;
435 }
436 }
437 }
438 else
439 {
440 if (s->bit_rate == 2400)
441 {
442 if (++s->tx.training_count >= ms_to_symbols(500))
443 {
444 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (C)\n");
445 s->tx.training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
446 s->tx.training_count = 0;
447 }
448 }
449 else
450 {
451 if (++s->tx.training_count >= ms_to_symbols(756))
452 {
453 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
454 s->tx.training = 0;
455 s->tx.training_count = 0;
456 }
457 }
458 }
459 break;
460 case V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400:
461 /* Segment 4: Scrambled ones at 2400bps. */
462 bits = scramble(s, 1);
463 bits = (bits << 1) | scramble(s, 1);
464 s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
465 bits = scramble(s, 1);
466 bits = (bits << 1) | scramble(s, 1);
467 z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
468 if (++s->tx.training_count >= ms_to_symbols(200))
469 {
470 /* We have completed training. Now handle some real work. */
471 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
472 s->tx.training = 0;
473 s->tx.training_count = 0;
474 s->tx.current_get_bit = s->get_bit;
475 }
476 break;
477 case V22BIS_TRAINING_STAGE_PARKED:
478 default:
479 z = complex_setf(0.0f, 0.0f);
480 break;
481 }
482 return z;
483 }
484 /*- End of function --------------------------------------------------------*/
485
getbaud(v22bis_state_t * s)486 static complexf_t getbaud(v22bis_state_t *s)
487 {
488 int bits;
489
490 if (s->tx.training)
491 {
492 /* Send the training sequence */
493 return training_get(s);
494 }
495
496 /* There is no graceful shutdown procedure defined for V.22bis. Just
497 send some ones, to ensure we get the real data bits through, even
498 with bad ISI. */
499 if (s->tx.shutdown)
500 {
501 if (++s->tx.shutdown > 10)
502 return complex_setf(0.0f, 0.0f);
503 }
504 /* The first two bits define the quadrant */
505 bits = get_scrambled_bit(s);
506 bits = (bits << 1) | get_scrambled_bit(s);
507 s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
508 if (s->bit_rate == 1200)
509 {
510 bits = 0x01;
511 }
512 else
513 {
514 /* The other two bits define the position within the quadrant */
515 bits = get_scrambled_bit(s);
516 bits = (bits << 1) | get_scrambled_bit(s);
517 }
518 return v22bis_constellation[(s->tx.constellation_state << 2) | bits];
519 }
520 /*- End of function --------------------------------------------------------*/
521
v22bis_tx(v22bis_state_t * s,int16_t amp[],int len)522 int v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
523 {
524 complexf_t x;
525 complexf_t z;
526 int i;
527 int sample;
528 float famp;
529
530 if (s->tx.shutdown > 10)
531 return 0;
532 for (sample = 0; sample < len; sample++)
533 {
534 if ((s->tx.baud_phase += 3) >= 40)
535 {
536 s->tx.baud_phase -= 40;
537 s->tx.rrc_filter[s->tx.rrc_filter_step] =
538 s->tx.rrc_filter[s->tx.rrc_filter_step + V22BIS_TX_FILTER_STEPS] = getbaud(s);
539 if (++s->tx.rrc_filter_step >= V22BIS_TX_FILTER_STEPS)
540 s->tx.rrc_filter_step = 0;
541 }
542 /* Root raised cosine pulse shaping at baseband */
543 x = complex_setf(0.0f, 0.0f);
544 for (i = 0; i < V22BIS_TX_FILTER_STEPS; i++)
545 {
546 x.re += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].re;
547 x.im += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].im;
548 }
549 /* Now create and modulate the carrier */
550 z = dds_complexf(&(s->tx.carrier_phase), s->tx.carrier_phase_rate);
551 famp = (x.re*z.re - x.im*z.im)*s->tx.gain;
552 if (s->tx.guard_phase_rate && (s->tx.rrc_filter[s->tx.rrc_filter_step].re != 0.0f || s->tx.rrc_filter[i + s->tx.rrc_filter_step].im != 0.0f))
553 {
554 /* Add the guard tone */
555 famp += dds_modf(&(s->tx.guard_phase), s->tx.guard_phase_rate, s->tx.guard_level, 0);
556 }
557 /* Don't bother saturating. We should never clip. */
558 amp[sample] = (int16_t) lrintf(famp);
559 }
560 return sample;
561 }
562 /*- End of function --------------------------------------------------------*/
563
v22bis_tx_power(v22bis_state_t * s,float power)564 void v22bis_tx_power(v22bis_state_t *s, float power)
565 {
566 float l;
567
568 l = 1.6f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f);
569 s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
570 }
571 /*- End of function --------------------------------------------------------*/
572
v22bis_tx_restart(v22bis_state_t * s,int bit_rate)573 static int v22bis_tx_restart(v22bis_state_t *s, int bit_rate)
574 {
575 s->bit_rate = bit_rate;
576 cvec_zerof(s->tx.rrc_filter, sizeof(s->tx.rrc_filter)/sizeof(s->tx.rrc_filter[0]));
577 s->tx.rrc_filter_step = 0;
578 s->tx.scramble_reg = 0;
579 s->tx.scrambler_pattern_count = 0;
580 s->tx.training = V22BIS_TRAINING_STAGE_INITIAL_SILENCE;
581 s->tx.training_count = 0;
582 s->tx.carrier_phase = 0;
583 s->tx.guard_phase = 0;
584 s->tx.baud_phase = 0;
585 s->tx.constellation_state = 0;
586 s->tx.current_get_bit = fake_get_bit;
587 s->tx.shutdown = 0;
588 return 0;
589 }
590 /*- End of function --------------------------------------------------------*/
591
v22bis_set_get_bit(v22bis_state_t * s,get_bit_func_t get_bit,void * user_data)592 void v22bis_set_get_bit(v22bis_state_t *s, get_bit_func_t get_bit, void *user_data)
593 {
594 s->get_bit = get_bit;
595 s->user_data = user_data;
596 }
597 /*- End of function --------------------------------------------------------*/
598
v22bis_set_put_bit(v22bis_state_t * s,put_bit_func_t put_bit,void * user_data)599 void v22bis_set_put_bit(v22bis_state_t *s, put_bit_func_t put_bit, void *user_data)
600 {
601 s->put_bit = put_bit;
602 s->user_data = user_data;
603 }
604 /*- End of function --------------------------------------------------------*/
605
v22bis_restart(v22bis_state_t * s,int bit_rate)606 int v22bis_restart(v22bis_state_t *s, int bit_rate)
607 {
608 if (bit_rate != 2400 && bit_rate != 1200)
609 return -1;
610 if (v22bis_tx_restart(s, bit_rate))
611 return -1;
612 return v22bis_rx_restart(s, bit_rate);
613 }
614 /*- End of function --------------------------------------------------------*/
615
v22bis_init(v22bis_state_t * s,int bit_rate,int guard,int caller,get_bit_func_t get_bit,put_bit_func_t put_bit,void * user_data)616 v22bis_state_t *v22bis_init(v22bis_state_t *s,
617 int bit_rate,
618 int guard,
619 int caller,
620 get_bit_func_t get_bit,
621 put_bit_func_t put_bit,
622 void *user_data)
623 {
624 if (s == NULL)
625 {
626 if ((s = (v22bis_state_t *) malloc(sizeof(*s))) == NULL)
627 return NULL;
628 }
629 memset(s, 0, sizeof(*s));
630 span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
631 span_log_set_protocol(&s->logging, "V.22bis");
632 s->bit_rate = bit_rate;
633 s->caller = caller;
634
635 s->get_bit = get_bit;
636 s->put_bit = put_bit;
637 s->user_data = user_data;
638
639 if (s->caller)
640 {
641 s->tx.carrier_phase_rate = dds_phase_ratef(1200.0f);
642 }
643 else
644 {
645 s->tx.carrier_phase_rate = dds_phase_ratef(2400.0f);
646 if (guard)
647 {
648 if (guard == 1)
649 {
650 s->tx.guard_phase_rate = dds_phase_ratef(550.0f);
651 s->tx.guard_level = 1500.0f;
652 }
653 else
654 {
655 s->tx.guard_phase_rate = dds_phase_ratef(1800.0f);
656 s->tx.guard_level = 1000.0f;
657 }
658 }
659 }
660 v22bis_tx_power(s, -10.0f);
661 v22bis_restart(s, s->bit_rate);
662 return s;
663 }
664 /*- End of function --------------------------------------------------------*/
665
v22bis_free(v22bis_state_t * s)666 int v22bis_free(v22bis_state_t *s)
667 {
668 free(s);
669 return 0;
670 }
671 /*- End of function --------------------------------------------------------*/
672 /*- End of file ------------------------------------------------------------*/
673