5
|
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 General Public License version 2, as
|
|
14 * 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 General Public License for more details.
|
|
20 *
|
|
21 * You should have received a copy of the GNU General Public License
|
|
22 * 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.34 2006/11/28 16:59:57 steveu Exp $
|
|
26 */
|
|
27
|
|
28 /*! \file */
|
|
29
|
|
30 /* THIS IS A WORK IN PROGRESS - NOT YET FUNCTIONAL! */
|
|
31
|
|
32 #ifdef 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 #if defined(HAVE_TGMATH_H)
|
|
41 #include <tgmath.h>
|
|
42 #endif
|
|
43 #if defined(HAVE_MATH_H)
|
|
44 #include <math.h>
|
|
45 #endif
|
|
46
|
|
47 #include "spandsp/telephony.h"
|
|
48 #include "spandsp/logging.h"
|
|
49 #include "spandsp/complex.h"
|
|
50 #include "spandsp/vector_float.h"
|
|
51 #include "spandsp/complex_vector_float.h"
|
|
52 #include "spandsp/async.h"
|
|
53 #include "spandsp/dds.h"
|
|
54 #include "spandsp/power_meter.h"
|
|
55
|
|
56 #include "spandsp/v29rx.h"
|
|
57 #include "spandsp/v22bis.h"
|
|
58
|
|
59 /* Quoting from the V.22bis spec.
|
|
60
|
|
61 6.3.1.1 Interworking at 2400 bit/s
|
|
62
|
|
63 6.3.1.1.1 Calling modem
|
|
64
|
|
65 a) On connection to line the calling modem shall be conditioned to receive signals
|
|
66 in the high channel at 1200 bit/s and transmit signals in the low channel at 1200 bit/s
|
|
67 in accordance with section 2.5.2.2. It shall apply an ON condition to circuit 107 in accordance
|
|
68 with Recommendation V.25. The modem shall initially remain silent.
|
|
69
|
|
70 b) After 155 +-10 ms of unscrambled binary 1 has been detected, the modem shall remain silent
|
|
71 for a further 456 +-10 ms then transmit an unscrambled repetitive double dibit pattern of 00
|
|
72 and 11 at 1200 bit/s for 100 +-3 ms. Following this signal the modem shall transmit scrambled
|
|
73 binary 1 at 1200 bit/s.
|
|
74
|
|
75 c) If the modem detects scrambled binary 1 in the high channel at 1200 bit/s for 270 +-40 ms,
|
|
76 the handshake shall continue in accordance with section 6.3.1.2.1 c) and d). However, if unscrambled
|
|
77 repetitive double dibit 00 and 11 at 1200 bit/s is detected in the high channel, then at the
|
|
78 end of receipt of this signal the modem shall apply an ON condition to circuit 112.
|
|
79
|
|
80 d) 600 +-10 ms after circuit 112 has been turned ON the modem shall begin transmitting scrambled
|
|
81 binary 1 at 2400 bit/s, and 450 +-10 ms after circuit 112 has been turned ON the receiver may
|
|
82 begin making 16-way decisions.
|
|
83
|
|
84 e) Following transmission of scrambled binary 1 at 2400 bit/s for 200 +-10 ms, circuit 106 shall
|
|
85 be conditioned to respond to circuit 105 and the modem shall be ready to transmit data at
|
|
86 2400 bit/s.
|
|
87
|
|
88 f) When 32 consecutive bits of scrambled binary 1 at 2400 bit/s have been detected in the high
|
|
89 channel the modem shall be ready to receive data at 2400 bit/s and shall apply an ON condition
|
|
90 to circuit 109.
|
|
91
|
|
92 6.3.1.1.2 Answering modem
|
|
93
|
|
94 a) On connection to line the answering modem shall be conditioned to transmit signals in the high
|
|
95 channel at 1200 bit/s in accordance with section 2.5.2.2 and receive signals in the low channel at
|
|
96 1200 bit/s. Following transmission of the answer sequence in accordance with Recommendation
|
|
97 V.25, the modem shall apply an ON condition to circuit 107 and then transmit unscrambled
|
|
98 binary 1 at 1200 bit/s.
|
|
99
|
|
100 b) If the modem detects scrambled binary 1 or 0 in the low channel at 1200 bit/s for 270 +-40 ms,
|
|
101 the handshake shall continue in accordance with section 6.3.1.2.2 b) and c). However, if unscrambled
|
|
102 repetitive double dibit 00 and 11 at 1200 bit/s is detected in the low channel, at the end of
|
|
103 receipt of this signal the modem shall apply an ON condition to circuit 112 and then transmit
|
|
104 an unscrambled repetitive double dibit pattern of 00 and 11 at 1200 bit/s for 100 +-3 ms.
|
|
105 Following these signals the modem shall transmit scrambled binary 1 at 1200 bit/s.
|
|
106
|
|
107 c) 600 +-10 ms after circuit 112 has been turned ON the modem shall begin transmitting scrambled
|
|
108 binary 1 at 2400 bit/s, and 450 +-10 ms after circuit 112 has been turned ON the receiver may
|
|
109 begin making 16-way decisions.
|
|
110
|
|
111 d) Following transmission of scrambled binary 1 at 2400 bit/s for 200 +-10 ms, circuit 106 shall
|
|
112 be conditioned to respond to circuit 105 and the modem shall be ready to transmit data at
|
|
113 2400 bit/s.
|
|
114
|
|
115 e) When 32 consecutive bits of scrambled binary 1 at 2400 bit/s have been detected in the low
|
|
116 channel the modem shall be ready to receive data at 2400 bit/s and shall apply an ON
|
|
117 condition to circuit 109.
|
|
118
|
|
119 6.3.1.2 Interworking at 1200 bit/s
|
|
120
|
|
121 The following handshake is identical to the Recommendation V.22 alternative A and B handshake.
|
|
122
|
|
123 6.3.1.2.1 Calling modem
|
|
124
|
|
125 a) On connection to line the calling modem shall be conditioned to receive signals in the high
|
|
126 channel at 1200 bit/s and transmit signals in the low channel at 1200 bit/s in accordance
|
|
127 with section 2.5.2.2. It shall apply an ON condition to circuit 107 in accordance with
|
|
128 Recommendation V.25. The modem shall initially remain silent.
|
|
129
|
|
130 b) After 155 +-10 ms of unscrambled binary 1 has been detected, the modem shall remain silent
|
|
131 for a further 456 +-10 ms then transmit scrambled binary 1 at 1200 bit/s (a preceding V.22 bis
|
|
132 signal, as shown in Figure 7/V.22 bis, would not affect the operation of a V.22 answer modem).
|
|
133
|
|
134 c) On detection of scrambled binary 1 in the high channel at 1200 bit/s for 270 +-40 ms the modem
|
|
135 shall be ready to receive data at 1200 bit/s and shall apply an ON condition to circuit 109 and
|
|
136 an OFF condition to circuit 112.
|
|
137
|
|
138 d) 765 +-10 ms after circuit 109 has been turned ON, circuit 106 shall be conditioned to respond
|
|
139 to circuit 105 and the modem shall be ready to transmit data at 1200 bit/s.
|
|
140
|
|
141 6.3.1.2.2 Answering modem
|
|
142
|
|
143 a) On connection to line the answering modem shall be conditioned to transmit signals in the high
|
|
144 channel at 1200 bit/s in accordance with section 2.5.2.2 and receive signals in the low channel at
|
|
145 1200 bit/s.
|
|
146
|
|
147 Following transmission of the answer sequence in accordance with V.25 the modem shall apply
|
|
148 an ON condition to circuit 107 and then transmit unscrambled binary 1 at 1200 bit/s.
|
|
149
|
|
150 b) On detection of scrambled binary 1 or 0 in the low channel at 1200 bit/s for 270 +-40 ms the
|
|
151 modem shall apply an OFF condition to circuit 112 and shall then transmit scrambled binary 1
|
|
152 at 1200 bit/s.
|
|
153
|
|
154 c) After scrambled binary 1 has been transmitted at 1200 bit/s for 765 +-10 ms the modem shall be
|
|
155 ready to transmit and receive data at 1200 bit/s, shall condition circuit 106 to respond to
|
|
156 circuit 105 and shall apply an ON condition to circuit 109.
|
|
157
|
|
158 Note - Manufacturers may wish to note that in certain countries, for national purposes, modems are
|
|
159 in service which emit an answering tone of 2225 Hz instead of unscrambled binary 1.
|
|
160
|
|
161
|
|
162 V.22bis to V.22bis
|
|
163 ------------------
|
|
164 Calling party
|
|
165 S1 scrambled 1's scrambled 1's data
|
|
166 at 1200bps at 2400bps
|
|
167 |---------------------------------------------------------|XXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
168 |<155+-10>|<456+-10>|<100+-3>| |<------600+-10------>|<---200+-10-->|
|
|
169 ^ | ^<----450+-100---->|[16 way decisions begin]
|
|
170 | | |
|
|
171 | v |
|
|
172 | |<------450+-100----->|[16 way decisions begin]
|
|
173 | |<----------600+-10-------->|
|
|
174 |<2150+-350>|<--3300+-700->|<75+-20>| |<100+-3>| |<---200+-10-->
|
|
175 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXX|XXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
176 silence 2100Hz unscrambled 1's S1 scrambled 1's scrambled 1's data
|
|
177 at 1200bps at 1200bps at 2400bps
|
|
178 Answering party
|
|
179
|
|
180 S1 = Unscrambled double dibit 00 and 11 at 1200bps
|
|
181 When the 2400bps section starts, both sides should look for 32 bits of continuous ones, as a test of integrity.
|
|
182
|
|
183
|
|
184
|
|
185
|
|
186 V.22 to V.22bis
|
|
187 ---------------
|
|
188 Calling party
|
|
189 scrambled 1's data
|
|
190 at 1200bps
|
|
191 |---------------------------------------------------------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
192 |<155+-10>|<456+-10>| |<270+-40>|<--------765+-10-------->|
|
|
193 ^ | ^
|
|
194 | | |
|
|
195 | | |
|
|
196 | | |
|
|
197 | v |
|
|
198 |<2150+-350>|<--3300+-700->|<75+-20>| |<270+-40>|<---------765+-10-------->|
|
|
199 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
200 silence 2100Hz unscrambled 1's scrambled 1's data
|
|
201 at 1200bps at 1200bps
|
|
202 Answering party
|
|
203
|
|
204 Both ends should accept unscrambled binary 1 or binary 0 as the preamble.
|
|
205
|
|
206
|
|
207
|
|
208
|
|
209 V.22bis to V.22
|
|
210 ---------------
|
|
211 Calling party
|
|
212 S1 scrambled 1's data
|
|
213 at 1200bps
|
|
214 |---------------------------------------------------------|XXXXXXXX|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
215 |<155+-10>|<456+-10>|<100+-3>| |<-270+-40-><------765+-10------>|
|
|
216 ^ | ^
|
|
217 | | |
|
|
218 | v |
|
|
219 | |
|
|
220 | |
|
|
221 |<2150+-350>|<--3300+-700->|<75+-20>| |<-270+-40->|<------765+-10----->|
|
|
222 |-----------|XXXXXXXXXXXXXX|--------|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXX
|
|
223 silence 2100Hz unscrambled 1's scrambled 1's data
|
|
224 at 1200bps at 1200bps
|
|
225 Answering party
|
|
226
|
|
227 Both ends should accept unscrambled binary 1 or binary 0 as the preamble.
|
|
228 */
|
|
229
|
|
230 #define ms_to_symbols(t) (((t)*600)/1000)
|
|
231
|
|
232 /* Segments of the training sequence */
|
|
233 enum
|
|
234 {
|
|
235 V22BIS_TRAINING_STAGE_NORMAL_OPERATION = 0,
|
|
236 V22BIS_TRAINING_STAGE_INITIAL_SILENCE,
|
|
237 V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES,
|
|
238 V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011,
|
|
239 V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200,
|
|
240 V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400,
|
|
241 V22BIS_TRAINING_STAGE_PARKED
|
|
242 };
|
|
243
|
|
244 static const int phase_steps[4] =
|
|
245 {
|
|
246 1, 0, 2, 3
|
|
247 };
|
|
248
|
|
249 const complexf_t v22bis_constellation[16] =
|
|
250 {
|
|
251 { 1.0f, 1.0f},
|
|
252 { 3.0f, 1.0f},
|
|
253 { 1.0f, 3.0f},
|
|
254 { 3.0f, 3.0f},
|
|
255 {-1.0f, 1.0f},
|
|
256 {-1.0f, 3.0f},
|
|
257 {-3.0f, 1.0f},
|
|
258 {-3.0f, 3.0f},
|
|
259 {-1.0f, -1.0f},
|
|
260 {-3.0f, -1.0f},
|
|
261 {-1.0f, -3.0f},
|
|
262 {-3.0f, -3.0f},
|
|
263 { 1.0f, -1.0f},
|
|
264 { 1.0f, -3.0f},
|
|
265 { 3.0f, -1.0f},
|
|
266 { 3.0f, -3.0f}
|
|
267 };
|
|
268
|
|
269 /* Raised root cosine pulse shaping; Beta = 0.75; 4 symbols either
|
|
270 side of the centre. */
|
|
271 /* Created with mkshape -r 0.0125 0.75 361 -l and then split up */
|
|
272 #define PULSESHAPER_GAIN (40.000612087f/40.0f)
|
|
273 #define PULSESHAPER_COEFF_SETS 40
|
|
274
|
|
275 static const float pulseshaper[PULSESHAPER_COEFF_SETS][V22BIS_TX_FILTER_STEPS] =
|
|
276 {
|
|
277 {
|
|
278 -0.0047287346f, /* Filter 0 */
|
|
279 -0.0083947197f,
|
|
280 -0.0087380763f,
|
|
281 0.0088053673f,
|
|
282 0.5108981827f,
|
|
283 0.5108981827f,
|
|
284 0.0088053673f,
|
|
285 -0.0087380763f,
|
|
286 -0.0083947197f
|
|
287 },
|
|
288 {
|
|
289 -0.0044638629f, /* Filter 1 */
|
|
290 -0.0089241700f,
|
|
291 -0.0111288952f,
|
|
292 0.0023412184f,
|
|
293 0.5623914901f,
|
|
294 0.4599551720f,
|
|
295 0.0144817755f,
|
|
296 -0.0063186648f,
|
|
297 -0.0077293609f
|
|
298 },
|
|
299 {
|
|
300 -0.0041048584f, /* Filter 2 */
|
|
301 -0.0093040596f,
|
|
302 -0.0134459768f,
|
|
303 -0.0048558766f,
|
|
304 0.6141017035f,
|
|
305 0.4098822897f,
|
|
306 0.0193317049f,
|
|
307 -0.0039145680f,
|
|
308 -0.0069438567f
|
|
309 },
|
|
310 {
|
|
311 -0.0036565006f, /* Filter 3 */
|
|
312 -0.0095231635f,
|
|
313 -0.0156437084f,
|
|
314 -0.0127148737f,
|
|
315 0.6656848457f,
|
|
316 0.3609830295f,
|
|
317 0.0233320755f,
|
|
318 -0.0015677363f,
|
|
319 -0.0060557371f
|
|
320 },
|
|
321 {
|
|
322 -0.0031253709f, /* Filter 4 */
|
|
323 -0.0095729633f,
|
|
324 -0.0176768181f,
|
|
325 -0.0211485021f,
|
|
326 0.7167894869f,
|
|
327 0.3135419896f,
|
|
328 0.0264748749f,
|
|
329 0.0006824956f,
|
|
330 -0.0050839319f
|
|
331 },
|
|
332 {
|
|
333 -0.0025197700f, /* Filter 5 */
|
|
334 -0.0094478866f,
|
|
335 -0.0195012095f,
|
|
336 -0.0300535107f,
|
|
337 0.7670600056f,
|
|
338 0.2678225635f,
|
|
339 0.0287663895f,
|
|
340 0.0027999985f,
|
|
341 -0.0040483891f
|
|
342 },
|
|
343 {
|
|
344 -0.0018496023f, /* Filter 6 */
|
|
345 -0.0091454978f,
|
|
346 -0.0210748106f,
|
|
347 -0.0393111426f,
|
|
348 0.8161399423f,
|
|
349 0.2240649005f,
|
|
350 0.0302262769f,
|
|
351 0.0047523617f,
|
|
352 -0.0029696854f
|
|
353 },
|
|
354 {
|
|
355 -0.0011262266f, /* Filter 7 */
|
|
356 -0.0086666380f,
|
|
357 -0.0223584207f,
|
|
358 -0.0487878398f,
|
|
359 0.8636754069f,
|
|
360 0.1824841563f,
|
|
361 0.0308864956f,
|
|
362 0.0065113237f,
|
|
363 -0.0018686358f
|
|
364 },
|
|
365 {
|
|
366 -0.0003622774f, /* Filter 8 */
|
|
367 -0.0080155088f,
|
|
368 -0.0233165437f,
|
|
369 -0.0583361774f,
|
|
370 0.9093185032f,
|
|
371 0.1432690480f,
|
|
372 0.0307901140f,
|
|
373 0.0080531155f,
|
|
374 -0.0007659096f
|
|
375 },
|
|
376 {
|
|
377 0.0004285425f, /* Filter 9 */
|
|
378 -0.0071996967f,
|
|
379 -0.0239181901f,
|
|
380 -0.0677960213f,
|
|
381 0.9527307304f,
|
|
382 0.1065807242f,
|
|
383 0.0299900191f,
|
|
384 0.0093587151f,
|
|
385 0.0003183408f
|
|
386 },
|
|
387 {
|
|
388 0.0012316933f, /* Filter 10 */
|
|
389 -0.0062301368f,
|
|
390 -0.0241376359f,
|
|
391 -0.0769959031f,
|
|
392 0.9935863233f,
|
|
393 0.0725519600f,
|
|
394 0.0285475474f,
|
|
395 0.0104140102f,
|
|
396 0.0013648323f
|
|
397 },
|
|
398 {
|
|
399 0.0020320508f, /* Filter 11 */
|
|
400 -0.0051210137f,
|
|
401 -0.0239551212f,
|
|
402 -0.0857546018f,
|
|
403 1.0315754934f,
|
|
404 0.0412866769f,
|
|
405 0.0265310587f,
|
|
406 0.0112098711f,
|
|
407 0.0023554782f
|
|
408 },
|
|
409 {
|
|
410 0.0028141763f, /* Filter 12 */
|
|
411 -0.0038896008f,
|
|
412 -0.0233574765f,
|
|
413 -0.0938829156f,
|
|
414 1.0664075323f,
|
|
415 0.0128597894f,
|
|
416 0.0240144782f,
|
|
417 0.0117421344f,
|
|
418 0.0032736852f
|
|
419 },
|
|
420 {
|
|
421 0.0035625973f, /* Filter 13 */
|
|
422 -0.0025560369f,
|
|
423 -0.0223386620f,
|
|
424 -0.1011856112f,
|
|
425 1.0978137424f,
|
|
426 -0.0126826277f,
|
|
427 0.0210758250f,
|
|
428 0.0120115019f,
|
|
429 0.0041046165f
|
|
430 },
|
|
431 {
|
|
432 0.0042620971f, /* Filter 14 */
|
|
433 -0.0011430452f,
|
|
434 -0.0209002083f,
|
|
435 -0.1074635265f,
|
|
436 1.1255501596f,
|
|
437 -0.0353228594f,
|
|
438 0.0177957527f,
|
|
439 0.0120233576f,
|
|
440 0.0048354157f
|
|
441 },
|
|
442 {
|
|
443 0.0048980053f, /* Filter 15 */
|
|
444 0.0003244045f,
|
|
445 -0.0190515462f,
|
|
446 -0.1125158080f,
|
|
447 1.1494000377f,
|
|
448 -0.0550707703f,
|
|
449 0.0142561191f,
|
|
450 0.0117875105f,
|
|
451 0.0054553898f
|
|
452 },
|
|
453 {
|
|
454 0.0054564857f, /* Filter 16 */
|
|
455 0.0018194852f,
|
|
456 -0.0168102168f,
|
|
457 -0.1161422557f,
|
|
458 1.1691760633f,
|
|
459 -0.0719627404f,
|
|
460 0.0105386068f,
|
|
461 0.0113178688f,
|
|
462 0.0059561483f
|
|
463 },
|
|
464 {
|
|
465 0.0059248154f, /* Filter 17 */
|
|
466 0.0033139475f,
|
|
467 -0.0142019526f,
|
|
468 -0.1181457502f,
|
|
469 1.1847222770f,
|
|
470 -0.0860603350f,
|
|
471 0.0067234125f,
|
|
472 0.0106320540f,
|
|
473 0.0063316975f
|
|
474 },
|
|
475 {
|
|
476 0.0062916504f, /* Filter 18 */
|
|
477 0.0047785946f,
|
|
478 -0.0112606234f,
|
|
479 -0.1183347329f,
|
|
480 1.1959156771f,
|
|
481 -0.0974487311f,
|
|
482 0.0028880206f,
|
|
483 0.0097509621f,
|
|
484 0.0065784888f
|
|
485 },
|
|
486 {
|
|
487 0.0065472715f, /* Filter 19 */
|
|
488 0.0061837898f,
|
|
489 -0.0080280420f,
|
|
490 -0.1165257094f,
|
|
491 1.2026674866f,
|
|
492 -0.1062349247f,
|
|
493 -0.0008939235f,
|
|
494 0.0086982833f,
|
|
495 0.0066954225f
|
|
496 },
|
|
497 {
|
|
498 0.0066838062f, /* Filter 20 */
|
|
499 0.0074999881f,
|
|
500 -0.0045536271f,
|
|
501 -0.1125457458f,
|
|
502 1.2049240699f,
|
|
503 -0.1125457458f,
|
|
504 -0.0045536271f,
|
|
505 0.0074999881f,
|
|
506 0.0066838062f
|
|
507 },
|
|
508 {
|
|
509 0.0066954225f, /* Filter 21 */
|
|
510 0.0086982833f,
|
|
511 -0.0008939235f,
|
|
512 -0.1062349247f,
|
|
513 1.2026674866f,
|
|
514 -0.1165257094f,
|
|
515 -0.0080280420f,
|
|
516 0.0061837898f,
|
|
517 0.0065472715f
|
|
518 },
|
|
519 {
|
|
520 0.0065784888f, /* Filter 22 */
|
|
521 0.0097509621f,
|
|
522 0.0028880206f,
|
|
523 -0.0974487311f,
|
|
524 1.1959156771f,
|
|
525 -0.1183347329f,
|
|
526 -0.0112606234f,
|
|
527 0.0047785946f,
|
|
528 0.0062916504f
|
|
529 },
|
|
530 {
|
|
531 0.0063316975f, /* Filter 23 */
|
|
532 0.0106320540f,
|
|
533 0.0067234125f,
|
|
534 -0.0860603350f,
|
|
535 1.1847222770f,
|
|
536 -0.1181457502f,
|
|
537 -0.0142019526f,
|
|
538 0.0033139475f,
|
|
539 0.0059248154f
|
|
540 },
|
|
541 {
|
|
542 0.0059561483f, /* Filter 24 */
|
|
543 0.0113178688f,
|
|
544 0.0105386068f,
|
|
545 -0.0719627404f,
|
|
546 1.1691760633f,
|
|
547 -0.1161422557f,
|
|
548 -0.0168102168f,
|
|
549 0.0018194852f,
|
|
550 0.0054564857f
|
|
551 },
|
|
552 {
|
|
553 0.0054553898f, /* Filter 25 */
|
|
554 0.0117875105f,
|
|
555 0.0142561191f,
|
|
556 -0.0550707703f,
|
|
557 1.1494000377f,
|
|
558 -0.1125158080f,
|
|
559 -0.0190515462f,
|
|
560 0.0003244045f,
|
|
561 0.0048980053f
|
|
562 },
|
|
563 {
|
|
564 0.0048354157f, /* Filter 26 */
|
|
565 0.0120233576f,
|
|
566 0.0177957527f,
|
|
567 -0.0353228594f,
|
|
568 1.1255501596f,
|
|
569 -0.1074635265f,
|
|
570 -0.0209002083f,
|
|
571 -0.0011430452f,
|
|
572 0.0042620971f
|
|
573 },
|
|
574 {
|
|
575 0.0041046165f, /* Filter 27 */
|
|
576 0.0120115019f,
|
|
577 0.0210758250f,
|
|
578 -0.0126826277f,
|
|
579 1.0978137424f,
|
|
580 -0.1011856112f,
|
|
581 -0.0223386620f,
|
|
582 -0.0025560369f,
|
|
583 0.0035625973f
|
|
584 },
|
|
585 {
|
|
586 0.0032736852f, /* Filter 28 */
|
|
587 0.0117421344f,
|
|
588 0.0240144782f,
|
|
589 0.0128597894f,
|
|
590 1.0664075323f,
|
|
591 -0.0938829156f,
|
|
592 -0.0233574765f,
|
|
593 -0.0038896008f,
|
|
594 0.0028141763f
|
|
595 },
|
|
596 {
|
|
597 0.0023554782f, /* Filter 29 */
|
|
598 0.0112098711f,
|
|
599 0.0265310587f,
|
|
600 0.0412866769f,
|
|
601 1.0315754934f,
|
|
602 -0.0857546018f,
|
|
603 -0.0239551212f,
|
|
604 -0.0051210137f,
|
|
605 0.0020320508f
|
|
606 },
|
|
607 {
|
|
608 0.0013648323f, /* Filter 30 */
|
|
609 0.0104140102f,
|
|
610 0.0285475474f,
|
|
611 0.0725519600f,
|
|
612 0.9935863233f,
|
|
613 -0.0769959031f,
|
|
614 -0.0241376359f,
|
|
615 -0.0062301368f,
|
|
616 0.0012316933f
|
|
617 },
|
|
618 {
|
|
619 0.0003183408f, /* Filter 31 */
|
|
620 0.0093587151f,
|
|
621 0.0299900191f,
|
|
622 0.1065807242f,
|
|
623 0.9527307304f,
|
|
624 -0.0677960213f,
|
|
625 -0.0239181901f,
|
|
626 -0.0071996967f,
|
|
627 0.0004285425f
|
|
628 },
|
|
629 {
|
|
630 -0.0007659096f, /* Filter 32 */
|
|
631 0.0080531155f,
|
|
632 0.0307901140f,
|
|
633 0.1432690480f,
|
|
634 0.9093185032f,
|
|
635 -0.0583361774f,
|
|
636 -0.0233165437f,
|
|
637 -0.0080155088f,
|
|
638 -0.0003622774f
|
|
639 },
|
|
640 {
|
|
641 -0.0018686358f, /* Filter 33 */
|
|
642 0.0065113237f,
|
|
643 0.0308864956f,
|
|
644 0.1824841563f,
|
|
645 0.8636754069f,
|
|
646 -0.0487878398f,
|
|
647 -0.0223584207f,
|
|
648 -0.0086666380f,
|
|
649 -0.0011262266f
|
|
650 },
|
|
651 {
|
|
652 -0.0029696854f, /* Filter 34 */
|
|
653 0.0047523617f,
|
|
654 0.0302262769f,
|
|
655 0.2240649005f,
|
|
656 0.8161399423f,
|
|
657 -0.0393111426f,
|
|
658 -0.0210748106f,
|
|
659 -0.0091454978f,
|
|
660 -0.0018496023f
|
|
661 },
|
|
662 {
|
|
663 -0.0040483891f, /* Filter 35 */
|
|
664 0.0027999985f,
|
|
665 0.0287663895f,
|
|
666 0.2678225635f,
|
|
667 0.7670600056f,
|
|
668 -0.0300535107f,
|
|
669 -0.0195012095f,
|
|
670 -0.0094478866f,
|
|
671 -0.0025197700f
|
|
672 },
|
|
673 {
|
|
674 -0.0050839319f, /* Filter 36 */
|
|
675 0.0006824956f,
|
|
676 0.0264748749f,
|
|
677 0.3135419896f,
|
|
678 0.7167894869f,
|
|
679 -0.0211485021f,
|
|
680 -0.0176768181f,
|
|
681 -0.0095729633f,
|
|
682 -0.0031253709f
|
|
683 },
|
|
684 {
|
|
685 -0.0060557371f, /* Filter 37 */
|
|
686 -0.0015677363f,
|
|
687 0.0233320755f,
|
|
688 0.3609830295f,
|
|
689 0.6656848457f,
|
|
690 -0.0127148737f,
|
|
691 -0.0156437084f,
|
|
692 -0.0095231635f,
|
|
693 -0.0036565006f
|
|
694 },
|
|
695 {
|
|
696 -0.0069438567f, /* Filter 38 */
|
|
697 -0.0039145680f,
|
|
698 0.0193317049f,
|
|
699 0.4098822897f,
|
|
700 0.6141017035f,
|
|
701 -0.0048558766f,
|
|
702 -0.0134459768f,
|
|
703 -0.0093040596f,
|
|
704 -0.0041048584f
|
|
705 },
|
|
706 {
|
|
707 -0.0077293609f, /* Filter 39 */
|
|
708 -0.0063186648f,
|
|
709 0.0144817755f,
|
|
710 0.4599551720f,
|
|
711 0.5623914901f,
|
|
712 0.0023412184f,
|
|
713 -0.0111288952f,
|
|
714 -0.0089241700f,
|
|
715 -0.0044638629f
|
|
716 },
|
|
717 };
|
|
718
|
|
719 static int fake_get_bit(void *user_data)
|
|
720 {
|
|
721 return 1;
|
|
722 }
|
|
723 /*- End of function --------------------------------------------------------*/
|
|
724
|
|
725 static __inline__ int scramble(v22bis_state_t *s, int bit)
|
|
726 {
|
|
727 int out_bit;
|
|
728
|
|
729 out_bit = (bit ^ (s->tx_scramble_reg >> 14) ^ (s->tx_scramble_reg >> 17)) & 1;
|
|
730 if (s->tx_scrambler_pattern_count >= 64)
|
|
731 {
|
|
732 out_bit ^= 1;
|
|
733 s->tx_scrambler_pattern_count = 0;
|
|
734 }
|
|
735 if (out_bit == 1)
|
|
736 s->tx_scrambler_pattern_count++;
|
|
737 else
|
|
738 s->tx_scrambler_pattern_count = 0;
|
|
739 s->tx_scramble_reg = (s->tx_scramble_reg << 1) | out_bit;
|
|
740 return out_bit;
|
|
741 }
|
|
742 /*- End of function --------------------------------------------------------*/
|
|
743
|
|
744 static __inline__ int get_scrambled_bit(v22bis_state_t *s)
|
|
745 {
|
|
746 int bit;
|
|
747
|
|
748 if ((bit = s->current_get_bit(s->user_data)) == PUTBIT_END_OF_DATA)
|
|
749 {
|
|
750 /* Fill out this symbol with ones, and prepare to send
|
|
751 the rest of the shutdown sequence. */
|
|
752 s->current_get_bit = fake_get_bit;
|
|
753 s->shutdown = 1;
|
|
754 bit = 1;
|
|
755 }
|
|
756 return scramble(s, bit);
|
|
757 }
|
|
758 /*- End of function --------------------------------------------------------*/
|
|
759
|
|
760 static complexf_t training_get(v22bis_state_t *s)
|
|
761 {
|
|
762 complexf_t z;
|
|
763 int bits;
|
|
764
|
|
765 /* V.22bis training sequence */
|
|
766 switch (s->tx_training)
|
|
767 {
|
|
768 case V22BIS_TRAINING_STAGE_INITIAL_SILENCE:
|
|
769 /* Segment 1: silence */
|
|
770 s->tx_constellation_state = 0;
|
|
771 z = complex_setf(0.0f, 0.0f);
|
|
772 if (s->caller)
|
|
773 {
|
|
774 /* The caller just waits for a signal from the far end, which should be unscrambled ones */
|
|
775 if (s->detected_unscrambled_ones_or_zeros)
|
|
776 {
|
|
777 if (s->bit_rate == 2400)
|
|
778 {
|
|
779 /* Try to establish at 2400bps */
|
|
780 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting unscrambled 0011 at 1200 (S1)\n");
|
|
781 s->tx_training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011;
|
|
782 }
|
|
783 else
|
|
784 {
|
|
785 /* Only try at 1200bps */
|
|
786 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 1200 (A)\n");
|
|
787 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
|
|
788 }
|
|
789 s->tx_training_count = 0;
|
|
790 }
|
|
791 }
|
|
792 else
|
|
793 {
|
|
794 /* The answerer waits 75ms, then sends unscrambled ones */
|
|
795 if (++s->tx_training_count >= ms_to_symbols(75))
|
|
796 {
|
|
797 /* Inital 75ms of silence is over */
|
|
798 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting unscrambled ones at 1200\n");
|
|
799 s->tx_training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES;
|
|
800 s->tx_training_count = 0;
|
|
801 }
|
|
802 }
|
|
803 break;
|
|
804 case V22BIS_TRAINING_STAGE_UNSCRAMBLED_ONES:
|
|
805 /* Segment 2: Continuous unscrambled ones at 1200bps (i.e. reversals). */
|
|
806 /* Only the answering modem sends unscrambled ones. It is the first thing exchanged between the modems. */
|
|
807 s->tx_constellation_state = (s->tx_constellation_state + phase_steps[3]) & 3;
|
|
808 z = v22bis_constellation[(s->tx_constellation_state << 2) | 0x01];
|
|
809 if (s->bit_rate == 2400 && s->detected_unscrambled_0011_ending)
|
|
810 {
|
|
811 /* We are allowed to use 2400bps, and the far end is requesting 2400bps. Result: we are going to
|
|
812 work at 2400bps */
|
|
813 span_log(&s->logging, SPAN_LOG_FLOW, "+++ [2400] starting unscrambled 0011 at 1200 (S1)\n");
|
|
814 s->tx_training = V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011;
|
|
815 s->tx_training_count = 0;
|
|
816 break;
|
|
817 }
|
|
818 if (s->detected_scrambled_ones_or_zeros_at_1200bps)
|
|
819 {
|
|
820 /* We are going to work at 1200bps. */
|
|
821 span_log(&s->logging, SPAN_LOG_FLOW, "+++ [1200] starting scrambled ones at 1200 (B)\n");
|
|
822 s->bit_rate = 1200;
|
|
823 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
|
|
824 s->tx_training_count = 0;
|
|
825 break;
|
|
826 }
|
|
827 break;
|
|
828 case V22BIS_TRAINING_STAGE_UNSCRAMBLED_0011:
|
|
829 /* Segment 3: Continuous unscrambled double dibit 00 11 at 1200bps. This is termed the S1 segment in
|
|
830 the V.22bis spec. It is only sent to request or accept 2400bps mode, and lasts 100+-3ms. After this
|
|
831 timed burst, we unconditionally change to sending scrambled ones at 1200bps. */
|
|
832 s->tx_constellation_state = (s->tx_constellation_state + phase_steps[(s->tx_training_count & 1) ? 3 : 0]) & 3;
|
|
833 span_log(&s->logging, SPAN_LOG_FLOW, "U0011 Tx 0x%02x\n", s->tx_constellation_state);
|
|
834 z = v22bis_constellation[(s->tx_constellation_state << 2) | 0x01];
|
|
835 if (++s->tx_training_count >= ms_to_symbols(100))
|
|
836 {
|
|
837 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 1200 (C)\n");
|
|
838 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200;
|
|
839 s->tx_training_count = 0;
|
|
840 }
|
|
841 break;
|
|
842 case V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_1200:
|
|
843 /* Segment 4: Scrambled ones at 1200bps. */
|
|
844 bits = scramble(s, 1);
|
|
845 bits = (bits << 1) | scramble(s, 1);
|
|
846 s->tx_constellation_state = (s->tx_constellation_state + phase_steps[bits]) & 3;
|
|
847 z = v22bis_constellation[(s->tx_constellation_state << 2) | 0x01];
|
|
848 if (s->caller)
|
|
849 {
|
|
850 if (s->detected_unscrambled_0011_ending)
|
|
851 {
|
|
852 /* Continue for a further 600+-10ms */
|
|
853 if (++s->tx_training_count >= ms_to_symbols(600))
|
|
854 {
|
|
855 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (A)\n");
|
|
856 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
|
|
857 s->tx_training_count = 0;
|
|
858 }
|
|
859 }
|
|
860 else if (s->detected_scrambled_ones_or_zeros_at_1200bps)
|
|
861 {
|
|
862 if (s->bit_rate == 2400)
|
|
863 {
|
|
864 /* Continue for a further 756+-10ms */
|
|
865 if (++s->tx_training_count >= ms_to_symbols(756))
|
|
866 {
|
|
867 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (B)\n");
|
|
868 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
|
|
869 s->tx_training_count = 0;
|
|
870 }
|
|
871 }
|
|
872 else
|
|
873 {
|
|
874 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
|
|
875 s->tx_training = V22BIS_TRAINING_STAGE_NORMAL_OPERATION;
|
|
876 s->tx_training_count = 0;
|
|
877 s->current_get_bit = s->get_bit;
|
|
878 }
|
|
879 }
|
|
880 }
|
|
881 else
|
|
882 {
|
|
883 if (s->bit_rate == 2400)
|
|
884 {
|
|
885 if (++s->tx_training_count >= ms_to_symbols(500))
|
|
886 {
|
|
887 span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting scrambled ones at 2400 (C)\n");
|
|
888 s->tx_training = V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400;
|
|
889 s->tx_training_count = 0;
|
|
890 }
|
|
891 }
|
|
892 else
|
|
893 {
|
|
894 if (++s->tx_training_count >= ms_to_symbols(756))
|
|
895 {
|
|
896 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
|
|
897 s->tx_training = 0;
|
|
898 s->tx_training_count = 0;
|
|
899 }
|
|
900 }
|
|
901 }
|
|
902 break;
|
|
903 case V22BIS_TRAINING_STAGE_SCRAMBLED_ONES_AT_2400:
|
|
904 /* Segment 4: Scrambled ones at 2400bps. */
|
|
905 bits = scramble(s, 1);
|
|
906 bits = (bits << 1) | scramble(s, 1);
|
|
907 s->tx_constellation_state = (s->tx_constellation_state + phase_steps[bits]) & 3;
|
|
908 bits = scramble(s, 1);
|
|
909 bits = (bits << 1) | scramble(s, 1);
|
|
910 z = v22bis_constellation[(s->tx_constellation_state << 2) | 0x01];
|
|
911 if (++s->tx_training_count >= ms_to_symbols(200))
|
|
912 {
|
|
913 /* We have completed training. Now handle some real work. */
|
|
914 span_log(&s->logging, SPAN_LOG_FLOW, "+++ finished\n");
|
|
915 s->tx_training = 0;
|
|
916 s->tx_training_count = 0;
|
|
917 s->current_get_bit = s->get_bit;
|
|
918 }
|
|
919 break;
|
|
920 case V22BIS_TRAINING_STAGE_PARKED:
|
|
921 default:
|
|
922 z = complex_setf(0.0f, 0.0f);
|
|
923 break;
|
|
924 }
|
|
925 return z;
|
|
926 }
|
|
927 /*- End of function --------------------------------------------------------*/
|
|
928
|
|
929 static complexf_t getbaud(v22bis_state_t *s)
|
|
930 {
|
|
931 int bits;
|
|
932
|
|
933 if (s->tx_training)
|
|
934 {
|
|
935 /* Send the training sequence */
|
|
936 return training_get(s);
|
|
937 }
|
|
938
|
|
939 /* There is no graceful shutdown procedure defined for V.22bis. Just
|
|
940 send some ones, to ensure we get the real data bits through, even
|
|
941 with bad ISI. */
|
|
942 if (s->shutdown)
|
|
943 {
|
|
944 if (++s->shutdown > 10)
|
|
945 return complex_setf(0.0f, 0.0f);
|
|
946 }
|
|
947 /* The first two bits define the quadrant */
|
|
948 bits = get_scrambled_bit(s);
|
|
949 bits = (bits << 1) | get_scrambled_bit(s);
|
|
950 s->tx_constellation_state = (s->tx_constellation_state + phase_steps[bits]) & 3;
|
|
951 if (s->bit_rate == 1200)
|
|
952 {
|
|
953 bits = 0x01;
|
|
954 }
|
|
955 else
|
|
956 {
|
|
957 /* The other two bits define the position within the quadrant */
|
|
958 bits = get_scrambled_bit(s);
|
|
959 bits = (bits << 1) | get_scrambled_bit(s);
|
|
960 }
|
|
961 return v22bis_constellation[(s->tx_constellation_state << 2) | bits];
|
|
962 }
|
|
963 /*- End of function --------------------------------------------------------*/
|
|
964
|
|
965 int v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
|
|
966 {
|
|
967 complexf_t x;
|
|
968 complexf_t z;
|
|
969 int i;
|
|
970 int sample;
|
|
971 float famp;
|
|
972
|
|
973 if (s->shutdown > 10)
|
|
974 return 0;
|
|
975 for (sample = 0; sample < len; sample++)
|
|
976 {
|
|
977 if ((s->tx_baud_phase += 3) >= 40)
|
|
978 {
|
|
979 s->tx_baud_phase -= 40;
|
|
980 s->tx_rrc_filter[s->tx_rrc_filter_step] =
|
|
981 s->tx_rrc_filter[s->tx_rrc_filter_step + V22BIS_TX_FILTER_STEPS] = getbaud(s);
|
|
982 if (++s->tx_rrc_filter_step >= V22BIS_TX_FILTER_STEPS)
|
|
983 s->tx_rrc_filter_step = 0;
|
|
984 }
|
|
985 /* Root raised cosine pulse shaping at baseband */
|
|
986 x.re = 0.0f;
|
|
987 x.im = 0.0f;
|
|
988 for (i = 0; i < V22BIS_TX_FILTER_STEPS; i++)
|
|
989 {
|
|
990 x.re += pulseshaper[39 - s->tx_baud_phase][i]*s->tx_rrc_filter[i + s->tx_rrc_filter_step].re;
|
|
991 x.im += pulseshaper[39 - s->tx_baud_phase][i]*s->tx_rrc_filter[i + s->tx_rrc_filter_step].im;
|
|
992 }
|
|
993 /* Now create and modulate the carrier */
|
|
994 z = dds_complexf(&(s->tx_carrier_phase), s->tx_carrier_phase_rate);
|
|
995 famp = (x.re*z.re - x.im*z.im)*s->tx_gain;
|
|
996 if (s->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))
|
|
997 {
|
|
998 /* Add the guard tone */
|
|
999 famp += dds_modf(&(s->guard_phase), s->guard_phase_rate, s->guard_level, 0);
|
|
1000 }
|
|
1001 /* Don't bother saturating. We should never clip. */
|
|
1002 amp[sample] = (int16_t) lrintf(famp);
|
|
1003 }
|
|
1004 return sample;
|
|
1005 }
|
|
1006 /*- End of function --------------------------------------------------------*/
|
|
1007
|
|
1008 void v22bis_tx_power(v22bis_state_t *s, float power)
|
|
1009 {
|
|
1010 float l;
|
|
1011
|
|
1012 l = 1.6f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f);
|
|
1013 s->tx_gain = l*32768.0f/(PULSESHAPER_GAIN*3.0f);
|
|
1014 }
|
|
1015 /*- End of function --------------------------------------------------------*/
|
|
1016
|
|
1017 static int v22bis_tx_restart(v22bis_state_t *s, int bit_rate)
|
|
1018 {
|
|
1019 s->bit_rate = bit_rate;
|
|
1020 cvec_zerof(s->tx_rrc_filter, sizeof(s->tx_rrc_filter)/sizeof(s->tx_rrc_filter[0]));
|
|
1021 s->tx_rrc_filter_step = 0;
|
|
1022 s->tx_scramble_reg = 0;
|
|
1023 s->tx_scrambler_pattern_count = 0;
|
|
1024 s->tx_training = V22BIS_TRAINING_STAGE_INITIAL_SILENCE;
|
|
1025 s->tx_training_count = 0;
|
|
1026 s->tx_carrier_phase = 0;
|
|
1027 s->guard_phase = 0;
|
|
1028 s->tx_baud_phase = 0;
|
|
1029 s->tx_constellation_state = 0;
|
|
1030 s->current_get_bit = fake_get_bit;
|
|
1031 s->shutdown = 0;
|
|
1032 return 0;
|
|
1033 }
|
|
1034 /*- End of function --------------------------------------------------------*/
|
|
1035
|
|
1036 void v22bis_set_get_bit(v22bis_state_t *s, get_bit_func_t get_bit, void *user_data)
|
|
1037 {
|
|
1038 s->get_bit = get_bit;
|
|
1039 s->user_data = user_data;
|
|
1040 }
|
|
1041 /*- End of function --------------------------------------------------------*/
|
|
1042
|
|
1043 void v22bis_set_put_bit(v22bis_state_t *s, put_bit_func_t put_bit, void *user_data)
|
|
1044 {
|
|
1045 s->put_bit = put_bit;
|
|
1046 s->user_data = user_data;
|
|
1047 }
|
|
1048 /*- End of function --------------------------------------------------------*/
|
|
1049
|
|
1050 int v22bis_restart(v22bis_state_t *s, int bit_rate)
|
|
1051 {
|
|
1052 if (v22bis_tx_restart(s, bit_rate))
|
|
1053 return -1;
|
|
1054 return v22bis_rx_restart(s, bit_rate);
|
|
1055 }
|
|
1056 /*- End of function --------------------------------------------------------*/
|
|
1057
|
|
1058 v22bis_state_t *v22bis_init(v22bis_state_t *s,
|
|
1059 int bit_rate,
|
|
1060 int guard,
|
|
1061 int caller,
|
|
1062 get_bit_func_t get_bit,
|
|
1063 put_bit_func_t put_bit,
|
|
1064 void *user_data)
|
|
1065 {
|
|
1066 if (s == NULL)
|
|
1067 {
|
|
1068 if ((s = (v22bis_state_t *) malloc(sizeof(*s))) == NULL)
|
|
1069 return NULL;
|
|
1070 }
|
|
1071 memset(s, 0, sizeof(*s));
|
|
1072 s->bit_rate = bit_rate;
|
|
1073 s->caller = caller;
|
|
1074
|
|
1075 s->get_bit = get_bit;
|
|
1076 s->put_bit = put_bit;
|
|
1077 s->user_data = user_data;
|
|
1078
|
|
1079 if (s->caller)
|
|
1080 {
|
|
1081 s->tx_carrier_phase_rate = dds_phase_ratef(1200.0f);
|
|
1082 }
|
|
1083 else
|
|
1084 {
|
|
1085 s->tx_carrier_phase_rate = dds_phase_ratef(2400.0f);
|
|
1086 if (guard)
|
|
1087 {
|
|
1088 if (guard == 1)
|
|
1089 {
|
|
1090 s->guard_phase_rate = dds_phase_ratef(550.0f);
|
|
1091 s->guard_level = 1500.0f;
|
|
1092 }
|
|
1093 else
|
|
1094 {
|
|
1095 s->guard_phase_rate = dds_phase_ratef(1800.0f);
|
|
1096 s->guard_level = 1000.0f;
|
|
1097 }
|
|
1098 }
|
|
1099 }
|
|
1100 v22bis_tx_power(s, -10.0f);
|
|
1101 span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
|
1102 span_log_set_protocol(&s->logging, "V.22bis");
|
|
1103 v22bis_restart(s, s->bit_rate);
|
|
1104 return s;
|
|
1105 }
|
|
1106 /*- End of function --------------------------------------------------------*/
|
|
1107 /*- End of file ------------------------------------------------------------*/
|