Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/src/fax.c @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
4:26cd8f1ef0b1 | 5:f762bf195c4b |
---|---|
1 //#define LOG_FAX_AUDIO | |
2 /* | |
3 * SpanDSP - a series of DSP components for telephony | |
4 * | |
5 * fax.c - Analogue line ITU T.30 FAX transfer processing | |
6 * | |
7 * Written by Steve Underwood <steveu@coppice.org> | |
8 * | |
9 * Copyright (C) 2003, 2005, 2006 Steve Underwood | |
10 * | |
11 * All rights reserved. | |
12 * | |
13 * This program is free software; you can redistribute it and/or modify | |
14 * it under the terms of the GNU General Public License version 2, as | |
15 * published by the Free Software Foundation. | |
16 * | |
17 * This program is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with this program; if not, write to the Free Software | |
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 * | |
26 * $Id: fax.c,v 1.52 2006/11/19 14:07:24 steveu Exp $ | |
27 */ | |
28 | |
29 /*! \file */ | |
30 | |
31 #ifdef HAVE_CONFIG_H | |
32 #include <config.h> | |
33 #endif | |
34 | |
35 #include <inttypes.h> | |
36 #include <stdlib.h> | |
37 #include <stdio.h> | |
38 #include <string.h> | |
39 #if defined(HAVE_TGMATH_H) | |
40 #include <tgmath.h> | |
41 #endif | |
42 #if defined(HAVE_MATH_H) | |
43 #include <math.h> | |
44 #endif | |
45 #include <assert.h> | |
46 #include <fcntl.h> | |
47 #include <time.h> | |
48 #if defined(LOG_FAX_AUDIO) | |
49 #include <unistd.h> | |
50 #endif | |
51 | |
52 #include <tiffio.h> | |
53 | |
54 #include "spandsp/telephony.h" | |
55 #include "spandsp/logging.h" | |
56 #include "spandsp/queue.h" | |
57 #include "spandsp/dc_restore.h" | |
58 #include "spandsp/power_meter.h" | |
59 #include "spandsp/complex.h" | |
60 #include "spandsp/tone_generate.h" | |
61 #include "spandsp/async.h" | |
62 #include "spandsp/hdlc.h" | |
63 #include "spandsp/silence_gen.h" | |
64 #include "spandsp/fsk.h" | |
65 #include "spandsp/v29rx.h" | |
66 #include "spandsp/v29tx.h" | |
67 #include "spandsp/v27ter_rx.h" | |
68 #include "spandsp/v27ter_tx.h" | |
69 #if defined(ENABLE_V17) | |
70 #include "spandsp/v17rx.h" | |
71 #include "spandsp/v17tx.h" | |
72 #endif | |
73 #include "spandsp/t4.h" | |
74 | |
75 #include "spandsp/t30_fcf.h" | |
76 #include "spandsp/t35.h" | |
77 #include "spandsp/t30.h" | |
78 | |
79 #include "spandsp/fax.h" | |
80 | |
81 static void fax_send_hdlc(void *user_data, const uint8_t *msg, int len) | |
82 { | |
83 fax_state_t *s; | |
84 | |
85 s = (fax_state_t *) user_data; | |
86 | |
87 hdlc_tx_frame(&(s->hdlctx), msg, len); | |
88 s->first_tx_hdlc_frame = FALSE; | |
89 } | |
90 /*- End of function --------------------------------------------------------*/ | |
91 | |
92 static int dummy_rx(void *s, const int16_t amp[], int len) | |
93 { | |
94 return 0; | |
95 } | |
96 /*- End of function --------------------------------------------------------*/ | |
97 | |
98 #if defined(ENABLE_V17) | |
99 static int early_v17_rx(void *user_data, const int16_t amp[], int len) | |
100 { | |
101 fax_state_t *s; | |
102 | |
103 s = (fax_state_t *) user_data; | |
104 v17_rx(&(s->v17rx), amp, len); | |
105 fsk_rx(&(s->v21rx), amp, len); | |
106 if (s->t30_state.rx_trained) | |
107 { | |
108 /* The fast modem has trained, so we no longer need to run the slow | |
109 one in parallel. */ | |
110 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&(s->v17rx))); | |
111 s->rx_handler = (span_rx_handler_t *) &v17_rx; | |
112 s->rx_user_data = &(s->v17rx); | |
113 } | |
114 return len; | |
115 } | |
116 /*- End of function --------------------------------------------------------*/ | |
117 #endif | |
118 | |
119 static int early_v27ter_rx(void *user_data, const int16_t amp[], int len) | |
120 { | |
121 fax_state_t *s; | |
122 | |
123 s = (fax_state_t *) user_data; | |
124 v27ter_rx(&(s->v27ter_rx), amp, len); | |
125 fsk_rx(&(s->v21rx), amp, len); | |
126 if (s->t30_state.rx_trained) | |
127 { | |
128 /* The fast modem has trained, so we no longer need to run the slow | |
129 one in parallel. */ | |
130 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&(s->v27ter_rx))); | |
131 s->rx_handler = (span_rx_handler_t *) &v27ter_rx; | |
132 s->rx_user_data = &(s->v27ter_rx); | |
133 } | |
134 return len; | |
135 } | |
136 /*- End of function --------------------------------------------------------*/ | |
137 | |
138 static int early_v29_rx(void *user_data, const int16_t amp[], int len) | |
139 { | |
140 fax_state_t *s; | |
141 | |
142 s = (fax_state_t *) user_data; | |
143 v29_rx(&(s->v29rx), amp, len); | |
144 fsk_rx(&(s->v21rx), amp, len); | |
145 if (s->t30_state.rx_trained) | |
146 { | |
147 /* The fast modem has trained, so we no longer need to run the slow | |
148 one in parallel. */ | |
149 span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&(s->v29rx))); | |
150 s->rx_handler = (span_rx_handler_t *) &v29_rx; | |
151 s->rx_user_data = &(s->v29rx); | |
152 } | |
153 return len; | |
154 } | |
155 /*- End of function --------------------------------------------------------*/ | |
156 | |
157 int fax_rx(fax_state_t *s, int16_t *amp, int len) | |
158 { | |
159 int i; | |
160 | |
161 #if defined(LOG_FAX_AUDIO) | |
162 if (s->fax_audio_rx_log >= 0) | |
163 write(s->fax_audio_rx_log, amp, len*sizeof(int16_t)); | |
164 #endif | |
165 for (i = 0; i < len; i++) | |
166 amp[i] = dc_restore(&(s->dc_restore), amp[i]); | |
167 s->rx_handler(s->rx_user_data, amp, len); | |
168 t30_timer_update(&(s->t30_state), len); | |
169 return 0; | |
170 } | |
171 /*- End of function --------------------------------------------------------*/ | |
172 | |
173 static int set_next_tx_type(fax_state_t *s) | |
174 { | |
175 if (s->next_tx_handler) | |
176 { | |
177 s->tx_handler = s->next_tx_handler; | |
178 s->tx_user_data = s->next_tx_user_data; | |
179 s->next_tx_handler = NULL; | |
180 return 0; | |
181 } | |
182 /* If there is nothing else to change to, so use zero length silence */ | |
183 silence_gen_alter(&(s->silence_gen), 0); | |
184 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
185 s->tx_user_data = &(s->silence_gen); | |
186 s->next_tx_handler = NULL; | |
187 s->transmit = FALSE; | |
188 return -1; | |
189 } | |
190 /*- End of function --------------------------------------------------------*/ | |
191 | |
192 int fax_tx(fax_state_t *s, int16_t *amp, int max_len) | |
193 { | |
194 int len; | |
195 #if defined(LOG_FAX_AUDIO) | |
196 int required_len; | |
197 | |
198 required_len = max_len; | |
199 #endif | |
200 len = 0; | |
201 if (s->transmit) | |
202 { | |
203 while ((len += s->tx_handler(s->tx_user_data, amp + len, max_len - len)) < max_len) | |
204 { | |
205 /* Allow for a change of tx handler within a block */ | |
206 if (set_next_tx_type(s) && s->current_tx_type != T30_MODEM_NONE && s->current_tx_type != T30_MODEM_DONE) | |
207 t30_send_complete(&(s->t30_state)); | |
208 if (!s->transmit) | |
209 { | |
210 if (s->transmit_on_idle) | |
211 { | |
212 /* Pad to the requested length with silence */ | |
213 memset(amp + len, 0, (max_len - len)*sizeof(int16_t)); | |
214 len = max_len; | |
215 } | |
216 break; | |
217 } | |
218 } | |
219 } | |
220 else | |
221 { | |
222 if (s->transmit_on_idle) | |
223 { | |
224 /* Pad to the requested length with silence */ | |
225 memset(amp, 0, max_len*sizeof(int16_t)); | |
226 len = max_len; | |
227 } | |
228 } | |
229 #if defined(LOG_FAX_AUDIO) | |
230 if (s->fax_audio_tx_log >= 0) | |
231 { | |
232 if (len < required_len) | |
233 memset(amp + len, 0, (required_len - len)*sizeof(int16_t)); | |
234 write(s->fax_audio_tx_log, amp, required_len*sizeof(int16_t)); | |
235 } | |
236 #endif | |
237 return len; | |
238 } | |
239 /*- End of function --------------------------------------------------------*/ | |
240 | |
241 static void fax_set_rx_type(void *user_data, int type, int short_train, int use_hdlc) | |
242 { | |
243 fax_state_t *s; | |
244 put_bit_func_t put_bit_func; | |
245 void *put_bit_user_data; | |
246 | |
247 s = (fax_state_t *) user_data; | |
248 span_log(&s->logging, SPAN_LOG_FLOW, "Set rx type %d\n", type); | |
249 if (s->current_rx_type == type) | |
250 return; | |
251 s->current_rx_type = type; | |
252 if (use_hdlc) | |
253 { | |
254 put_bit_func = (put_bit_func_t) hdlc_rx_put_bit; | |
255 put_bit_user_data = (void *) &(s->hdlcrx); | |
256 hdlc_rx_init(&(s->hdlcrx), FALSE, FALSE, 5, t30_hdlc_accept, &(s->t30_state)); | |
257 } | |
258 else | |
259 { | |
260 put_bit_func = t30_non_ecm_put_bit; | |
261 put_bit_user_data = (void *) &(s->t30_state); | |
262 } | |
263 switch (type) | |
264 { | |
265 case T30_MODEM_V21: | |
266 if (s->flush_handler) | |
267 s->flush_handler(s, s->flush_user_data, 3); | |
268 fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data); | |
269 s->rx_handler = (span_rx_handler_t *) &fsk_rx; | |
270 s->rx_user_data = &(s->v21rx); | |
271 break; | |
272 case T30_MODEM_V27TER_2400: | |
273 v27ter_rx_restart(&(s->v27ter_rx), 2400, FALSE); | |
274 v27ter_rx_set_put_bit(&(s->v27ter_rx), put_bit_func, put_bit_user_data); | |
275 s->rx_handler = (span_rx_handler_t *) &early_v27ter_rx; | |
276 s->rx_user_data = s; | |
277 break; | |
278 case T30_MODEM_V27TER_4800: | |
279 v27ter_rx_restart(&(s->v27ter_rx), 4800, FALSE); | |
280 v27ter_rx_set_put_bit(&(s->v27ter_rx), put_bit_func, put_bit_user_data); | |
281 s->rx_handler = (span_rx_handler_t *) &early_v27ter_rx; | |
282 s->rx_user_data = s; | |
283 break; | |
284 case T30_MODEM_V29_7200: | |
285 v29_rx_restart(&(s->v29rx), 7200, FALSE); | |
286 v29_rx_set_put_bit(&(s->v29rx), put_bit_func, put_bit_user_data); | |
287 s->rx_handler = (span_rx_handler_t *) &early_v29_rx; | |
288 s->rx_user_data = s; | |
289 break; | |
290 case T30_MODEM_V29_9600: | |
291 v29_rx_restart(&(s->v29rx), 9600, FALSE); | |
292 v29_rx_set_put_bit(&(s->v29rx), put_bit_func, put_bit_user_data); | |
293 s->rx_handler = (span_rx_handler_t *) &early_v29_rx; | |
294 s->rx_user_data = s; | |
295 break; | |
296 #if defined(ENABLE_V17) | |
297 case T30_MODEM_V17_7200: | |
298 v17_rx_restart(&(s->v17rx), 7200, short_train); | |
299 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data); | |
300 s->rx_handler = (span_rx_handler_t *) &early_v17_rx; | |
301 s->rx_user_data = s; | |
302 break; | |
303 case T30_MODEM_V17_9600: | |
304 v17_rx_restart(&(s->v17rx), 9600, short_train); | |
305 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data); | |
306 s->rx_handler = (span_rx_handler_t *) &early_v17_rx; | |
307 s->rx_user_data = s; | |
308 break; | |
309 case T30_MODEM_V17_12000: | |
310 v17_rx_restart(&(s->v17rx), 12000, short_train); | |
311 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data); | |
312 s->rx_handler = (span_rx_handler_t *) &early_v17_rx; | |
313 s->rx_user_data = s; | |
314 break; | |
315 case T30_MODEM_V17_14400: | |
316 v17_rx_restart(&(s->v17rx), 14400, short_train); | |
317 v17_rx_set_put_bit(&(s->v17rx), put_bit_func, put_bit_user_data); | |
318 s->rx_handler = (span_rx_handler_t *) &early_v17_rx; | |
319 s->rx_user_data = s; | |
320 break; | |
321 #endif | |
322 case T30_MODEM_DONE: | |
323 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); | |
324 default: | |
325 s->rx_handler = (span_rx_handler_t *) &dummy_rx; | |
326 s->rx_user_data = s; | |
327 break; | |
328 } | |
329 } | |
330 /*- End of function --------------------------------------------------------*/ | |
331 | |
332 static void fax_set_tx_type(void *user_data, int type, int short_train, int use_hdlc) | |
333 { | |
334 fax_state_t *s; | |
335 tone_gen_descriptor_t tone_desc; | |
336 get_bit_func_t get_bit_func; | |
337 void *get_bit_user_data; | |
338 | |
339 s = (fax_state_t *) user_data; | |
340 span_log(&s->logging, SPAN_LOG_FLOW, "Set tx type %d\n", type); | |
341 if (s->current_tx_type == type) | |
342 return; | |
343 s->first_tx_hdlc_frame = TRUE; | |
344 if (use_hdlc) | |
345 { | |
346 get_bit_func = (get_bit_func_t) hdlc_tx_get_bit; | |
347 get_bit_user_data = (void *) &(s->hdlctx); | |
348 } | |
349 else | |
350 { | |
351 get_bit_func = t30_non_ecm_get_bit; | |
352 get_bit_user_data = (void *) &(s->t30_state); | |
353 } | |
354 switch (type) | |
355 { | |
356 case T30_MODEM_PAUSE: | |
357 silence_gen_alter(&(s->silence_gen), ms_to_samples(short_train)); | |
358 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
359 s->tx_user_data = &(s->silence_gen); | |
360 s->next_tx_handler = NULL; | |
361 s->transmit = TRUE; | |
362 break; | |
363 case T30_MODEM_CNG: | |
364 /* 0.5s of 1100Hz+-38Hz + 3.0s of silence repeating. Timing +-15% */ | |
365 make_tone_gen_descriptor(&tone_desc, | |
366 1100, | |
367 -11, | |
368 0, | |
369 0, | |
370 500, | |
371 3000, | |
372 0, | |
373 0, | |
374 TRUE); | |
375 tone_gen_init(&(s->tone_gen), &tone_desc); | |
376 s->tx_handler = (span_tx_handler_t *) &tone_gen; | |
377 s->tx_user_data = &(s->tone_gen); | |
378 s->next_tx_handler = NULL; | |
379 s->transmit = TRUE; | |
380 break; | |
381 case T30_MODEM_CED: | |
382 /* 0.2s of silence, then 2.6s to 4s of 2100Hz+-15Hz tone, then 75ms of silence. The 75ms of silence | |
383 will be inserted by the pre V.21 pause we use for any switch to V.21. */ | |
384 silence_gen_alter(&(s->silence_gen), ms_to_samples(200)); | |
385 make_tone_gen_descriptor(&tone_desc, | |
386 2100, | |
387 -11, | |
388 0, | |
389 0, | |
390 2600, | |
391 0, | |
392 0, | |
393 0, | |
394 FALSE); | |
395 tone_gen_init(&(s->tone_gen), &tone_desc); | |
396 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
397 s->tx_user_data = &(s->silence_gen); | |
398 s->next_tx_handler = (span_tx_handler_t *) &tone_gen; | |
399 s->next_tx_user_data = &(s->tone_gen); | |
400 s->transmit = TRUE; | |
401 break; | |
402 case T30_MODEM_V21: | |
403 fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], get_bit_func, get_bit_user_data); | |
404 /* The spec says 1s +-15% of preamble. So, the minimum is 32 octets. */ | |
405 hdlc_tx_preamble(&(s->hdlctx), 32); | |
406 /* Pause before switching from phase C, as per T.30 5.3.2.2. If we omit this, the receiver | |
407 might not see the carrier fall between the high speed and low speed sections. In practice, | |
408 a 75ms gap before any V.21 transmission is harmless, adds little to the overall length of | |
409 a call, and ensures the receiving end is ready. */ | |
410 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
411 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
412 s->tx_user_data = &(s->silence_gen); | |
413 s->next_tx_handler = (span_tx_handler_t *) &fsk_tx; | |
414 s->next_tx_user_data = &(s->v21tx); | |
415 s->transmit = TRUE; | |
416 break; | |
417 case T30_MODEM_V27TER_2400: | |
418 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
419 v27ter_tx_restart(&(s->v27ter_tx), 2400, s->use_tep); | |
420 v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data); | |
421 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
422 s->tx_user_data = &(s->silence_gen); | |
423 s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx; | |
424 s->next_tx_user_data = &(s->v27ter_tx); | |
425 hdlc_tx_preamble(&(s->hdlctx), 60); | |
426 s->transmit = TRUE; | |
427 break; | |
428 case T30_MODEM_V27TER_4800: | |
429 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
430 v27ter_tx_restart(&(s->v27ter_tx), 4800, s->use_tep); | |
431 v27ter_tx_set_get_bit(&(s->v27ter_tx), get_bit_func, get_bit_user_data); | |
432 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
433 s->tx_user_data = &(s->silence_gen); | |
434 s->next_tx_handler = (span_tx_handler_t *) &v27ter_tx; | |
435 s->next_tx_user_data = &(s->v27ter_tx); | |
436 hdlc_tx_preamble(&(s->hdlctx), 120); | |
437 s->transmit = TRUE; | |
438 break; | |
439 case T30_MODEM_V29_7200: | |
440 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
441 v29_tx_restart(&(s->v29tx), 7200, s->use_tep); | |
442 v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data); | |
443 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
444 s->tx_user_data = &(s->silence_gen); | |
445 s->next_tx_handler = (span_tx_handler_t *) &v29_tx; | |
446 s->next_tx_user_data = &(s->v29tx); | |
447 hdlc_tx_preamble(&(s->hdlctx), 180); | |
448 s->transmit = TRUE; | |
449 break; | |
450 case T30_MODEM_V29_9600: | |
451 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
452 v29_tx_restart(&(s->v29tx), 9600, s->use_tep); | |
453 v29_tx_set_get_bit(&(s->v29tx), get_bit_func, get_bit_user_data); | |
454 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
455 s->tx_user_data = &(s->silence_gen); | |
456 s->next_tx_handler = (span_tx_handler_t *) &v29_tx; | |
457 s->next_tx_user_data = &(s->v29tx); | |
458 hdlc_tx_preamble(&(s->hdlctx), 240); | |
459 s->transmit = TRUE; | |
460 break; | |
461 #if defined(ENABLE_V17) | |
462 case T30_MODEM_V17_7200: | |
463 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
464 v17_tx_restart(&(s->v17tx), 7200, s->use_tep, short_train); | |
465 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); | |
466 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
467 s->tx_user_data = &(s->silence_gen); | |
468 s->next_tx_handler = (span_tx_handler_t *) &v17_tx; | |
469 s->next_tx_user_data = &(s->v17tx); | |
470 hdlc_tx_preamble(&(s->hdlctx), 180); | |
471 s->transmit = TRUE; | |
472 break; | |
473 case T30_MODEM_V17_9600: | |
474 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
475 v17_tx_restart(&(s->v17tx), 9600, s->use_tep, short_train); | |
476 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); | |
477 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
478 s->tx_user_data = &(s->silence_gen); | |
479 s->next_tx_handler = (span_tx_handler_t *) &v17_tx; | |
480 s->next_tx_user_data = &(s->v17tx); | |
481 hdlc_tx_preamble(&(s->hdlctx), 240); | |
482 s->transmit = TRUE; | |
483 break; | |
484 case T30_MODEM_V17_12000: | |
485 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
486 v17_tx_restart(&(s->v17tx), 12000, s->use_tep, short_train); | |
487 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); | |
488 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
489 s->tx_user_data = &(s->silence_gen); | |
490 s->next_tx_handler = (span_tx_handler_t *) &v17_tx; | |
491 s->next_tx_user_data = &(s->v17tx); | |
492 hdlc_tx_preamble(&(s->hdlctx), 300); | |
493 s->transmit = TRUE; | |
494 break; | |
495 case T30_MODEM_V17_14400: | |
496 silence_gen_alter(&(s->silence_gen), ms_to_samples(75)); | |
497 v17_tx_restart(&(s->v17tx), 14400, s->use_tep, short_train); | |
498 v17_tx_set_get_bit(&(s->v17tx), get_bit_func, get_bit_user_data); | |
499 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
500 s->tx_user_data = &(s->silence_gen); | |
501 s->next_tx_handler = (span_tx_handler_t *) &v17_tx; | |
502 s->next_tx_user_data = &(s->v17tx); | |
503 hdlc_tx_preamble(&(s->hdlctx), 360); | |
504 s->transmit = TRUE; | |
505 break; | |
506 #endif | |
507 case T30_MODEM_DONE: | |
508 span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n"); | |
509 /* Fall through */ | |
510 default: | |
511 silence_gen_alter(&(s->silence_gen), 0); | |
512 s->tx_handler = (span_tx_handler_t *) &silence_gen; | |
513 s->tx_user_data = &(s->silence_gen); | |
514 s->next_tx_handler = NULL; | |
515 s->transmit = FALSE; | |
516 break; | |
517 } | |
518 s->current_tx_type = type; | |
519 } | |
520 /*- End of function --------------------------------------------------------*/ | |
521 | |
522 void fax_set_transmit_on_idle(fax_state_t *s, int transmit_on_idle) | |
523 { | |
524 s->transmit_on_idle = transmit_on_idle; | |
525 } | |
526 /*- End of function --------------------------------------------------------*/ | |
527 | |
528 void fax_set_tep_mode(fax_state_t *s, int use_tep) | |
529 { | |
530 s->use_tep = use_tep; | |
531 } | |
532 /*- End of function --------------------------------------------------------*/ | |
533 | |
534 int fax_init(fax_state_t *s, int calling_party) | |
535 { | |
536 memset(s, 0, sizeof(*s)); | |
537 span_log_init(&s->logging, SPAN_LOG_NONE, NULL); | |
538 span_log_set_protocol(&s->logging, "FAX"); | |
539 t30_init(&(s->t30_state), | |
540 calling_party, | |
541 fax_set_rx_type, | |
542 (void *) s, | |
543 fax_set_tx_type, | |
544 (void *) s, | |
545 fax_send_hdlc, | |
546 (void *) s); | |
547 t30_set_supported_modems(&(s->t30_state), | |
548 #if defined(ENABLE_V17) | |
549 T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17); | |
550 #else | |
551 T30_SUPPORT_V27TER | T30_SUPPORT_V29); | |
552 #endif | |
553 hdlc_rx_init(&(s->hdlcrx), FALSE, FALSE, 5, t30_hdlc_accept, &(s->t30_state)); | |
554 fsk_rx_init(&(s->v21rx), &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &(s->hdlcrx)); | |
555 hdlc_tx_init(&(s->hdlctx), FALSE, 2, FALSE, t30_send_complete, &(s->t30_state)); | |
556 s->first_tx_hdlc_frame = TRUE; | |
557 fsk_tx_init(&(s->v21tx), &preset_fsk_specs[FSK_V21CH2], (get_bit_func_t) hdlc_tx_get_bit, &(s->hdlctx)); | |
558 #if defined(ENABLE_V17) | |
559 v17_rx_init(&(s->v17rx), 14400, t30_non_ecm_put_bit, &(s->t30_state)); | |
560 v17_tx_init(&(s->v17tx), 14400, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); | |
561 #endif | |
562 v29_rx_init(&(s->v29rx), 9600, t30_non_ecm_put_bit, &(s->t30_state)); | |
563 v29_rx_signal_cutoff(&(s->v29rx), -45.5); | |
564 v29_tx_init(&(s->v29tx), 9600, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); | |
565 v27ter_rx_init(&(s->v27ter_rx), 4800, t30_non_ecm_put_bit, &(s->t30_state)); | |
566 v27ter_tx_init(&(s->v27ter_tx), 4800, s->use_tep, t30_non_ecm_get_bit, &(s->t30_state)); | |
567 silence_gen_init(&(s->silence_gen), 0); | |
568 dc_restore_init(&(s->dc_restore)); | |
569 t30_restart(&(s->t30_state)); | |
570 #if defined(LOG_FAX_AUDIO) | |
571 { | |
572 char buf[100 + 1]; | |
573 struct tm *tm; | |
574 time_t now; | |
575 | |
576 time(&now); | |
577 tm = localtime(&now); | |
578 sprintf(buf, | |
579 "/tmp/fax-rx-audio-%x-%02d%02d%02d%02d%02d%02d", | |
580 s, | |
581 tm->tm_year%100, | |
582 tm->tm_mon + 1, | |
583 tm->tm_mday, | |
584 tm->tm_hour, | |
585 tm->tm_min, | |
586 tm->tm_sec); | |
587 s->fax_audio_rx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666); | |
588 sprintf(buf, | |
589 "/tmp/fax-tx-audio-%x-%02d%02d%02d%02d%02d%02d", | |
590 s, | |
591 tm->tm_year%100, | |
592 tm->tm_mon + 1, | |
593 tm->tm_mday, | |
594 tm->tm_hour, | |
595 tm->tm_min, | |
596 tm->tm_sec); | |
597 s->fax_audio_tx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666); | |
598 } | |
599 #endif | |
600 return 0; | |
601 } | |
602 /*- End of function --------------------------------------------------------*/ | |
603 | |
604 int fax_release(fax_state_t *s) | |
605 { | |
606 t30_release(&s->t30_state); | |
607 return 0; | |
608 } | |
609 /*- End of function --------------------------------------------------------*/ | |
610 | |
611 void fax_set_flush_handler(fax_state_t *s, fax_flush_handler_t *handler, void *user_data) | |
612 { | |
613 s->flush_handler = handler; | |
614 s->flush_user_data = user_data; | |
615 } | |
616 /*- End of function --------------------------------------------------------*/ | |
617 /*- End of file ------------------------------------------------------------*/ |