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