comparison spandsp-0.0.3/spandsp-0.0.3/tests/fax_decode.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 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * fax_decode.c - a simple FAX audio decoder
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2005 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: fax_decode.c,v 1.22 2006/11/19 14:07:27 steveu Exp $
26 */
27
28 /*! \page fax_decode_page FAX decoder
29 \section fax_decode_page_sec_1 What does it do?
30 ???.
31
32 \section fax_decode_tests_page_sec_2 How does it work?
33 ???.
34 */
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <inttypes.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #if defined(HAVE_TGMATH_H)
45 #include <tgmath.h>
46 #endif
47 #if defined(HAVE_MATH_H)
48 #include <math.h>
49 #endif
50 #include <assert.h>
51 #include <audiofile.h>
52 #include <tiffio.h>
53
54 #include "spandsp.h"
55
56 #define SAMPLES_PER_CHUNK 160
57
58 int decode_test = FALSE;
59
60 int rx_bits = 0;
61
62 t30_state_t t30_dummy;
63 t4_state_t t4_state;
64 int t4_up = FALSE;
65
66 static void print_frame(const char *io, const uint8_t *fr, int frlen)
67 {
68 int i;
69 int type;
70 const char *country;
71 const char *vendor;
72 const char *model;
73
74 fprintf(stderr, "%s %s:", io, t30_frametype(fr[2]));
75 for (i = 2; i < frlen; i++)
76 fprintf(stderr, " %02x", fr[i]);
77 fprintf(stderr, "\n");
78 type = fr[2] & 0xFE;
79 if (type == T30_DIS || type == T30_DTC || type == T30_DCS)
80 t30_decode_dis_dtc_dcs(&t30_dummy, fr, frlen);
81 if (type == T30_NSF)
82 {
83 if (t35_decode(&fr[3], frlen - 3, &country, &vendor, &model))
84 {
85 if (country)
86 printf("The remote was made in '%s'\n", country);
87 if (vendor)
88 printf("The remote was made by '%s'\n", vendor);
89 if (model)
90 printf("The remote is a '%s'\n", model);
91 }
92 }
93 }
94 /*- End of function --------------------------------------------------------*/
95
96 static void hdlc_accept(void *user_data, int ok, const uint8_t *msg, int len)
97 {
98 if (len < 0)
99 {
100 /* Special conditions */
101 switch (len)
102 {
103 case PUTBIT_CARRIER_UP:
104 fprintf(stderr, "Slow carrier up\n");
105 break;
106 case PUTBIT_CARRIER_DOWN:
107 fprintf(stderr, "Slow carrier down\n");
108 break;
109 case PUTBIT_FRAMING_OK:
110 case PUTBIT_ABORT:
111 /* Just ignore these */
112 break;
113 default:
114 fprintf(stderr, "Unexpected HDLC special length - %d!\n", len);
115 break;
116 }
117 return;
118 }
119
120 if (msg[0] != 0xFF || !(msg[1] == 0x03 || msg[1] == 0x13))
121 {
122 fprintf(stderr, "Bad frame header - %02x %02x", msg[0], msg[1]);
123 return;
124 }
125 print_frame("HDLC: ", msg, len);
126 }
127 /*- End of function --------------------------------------------------------*/
128
129 static void t4_begin(void)
130 {
131 t4_rx_set_rx_encoding(&t4_state, T4_COMPRESSION_ITU_T4_2D);
132 t4_rx_set_x_resolution(&t4_state, T4_X_RESOLUTION_R8);
133 t4_rx_set_y_resolution(&t4_state, T4_Y_RESOLUTION_STANDARD);
134 t4_rx_set_image_width(&t4_state, 1728);
135
136 t4_rx_start_page(&t4_state);
137 t4_up = TRUE;
138 }
139 /*- End of function --------------------------------------------------------*/
140
141 static void t4_end(void)
142 {
143 t4_stats_t stats;
144
145 if (!t4_up)
146 return;
147 t4_rx_end_page(&t4_state);
148 t4_get_transfer_statistics(&t4_state, &stats);
149 printf("Pages = %d\n", stats.pages_transferred);
150 printf("Image size = %dx%d\n", stats.width, stats.length);
151 printf("Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution);
152 printf("Bad rows = %d\n", stats.bad_rows);
153 printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
154 t4_up = FALSE;
155 }
156 /*- End of function --------------------------------------------------------*/
157
158 #if defined(ENABLE_V17)
159 static void v17_put_bit(void *user_data, int bit)
160 {
161 int end_of_page;
162
163 if (bit < 0)
164 {
165 /* Special conditions */
166 switch (bit)
167 {
168 case PUTBIT_TRAINING_FAILED:
169 //printf("V.17 Training failed\n");
170 break;
171 case PUTBIT_TRAINING_SUCCEEDED:
172 printf("V.17 Training succeeded\n");
173 t4_begin();
174 break;
175 case PUTBIT_CARRIER_UP:
176 //printf("V.17 Carrier up\n");
177 break;
178 case PUTBIT_CARRIER_DOWN:
179 //printf("V.17 Carrier down\n");
180 t4_end();
181 break;
182 default:
183 printf("V.17 Eh!\n");
184 break;
185 }
186 return;
187 }
188
189 end_of_page = t4_rx_putbit(&t4_state, bit);
190 if (end_of_page)
191 {
192 t4_end();
193 printf("End of page detected\n");
194 }
195 //printf("V.17 Rx bit %d - %d\n", rx_bits++, bit);
196 }
197 /*- End of function --------------------------------------------------------*/
198 #endif
199
200 static void v29_put_bit(void *user_data, int bit)
201 {
202 int end_of_page;
203
204 if (bit < 0)
205 {
206 /* Special conditions */
207 switch (bit)
208 {
209 case PUTBIT_TRAINING_FAILED:
210 //printf("V.29 Training failed\n");
211 break;
212 case PUTBIT_TRAINING_SUCCEEDED:
213 printf("V.29 Training succeeded\n");
214 t4_begin();
215 break;
216 case PUTBIT_CARRIER_UP:
217 //printf("V.29 Carrier up\n");
218 break;
219 case PUTBIT_CARRIER_DOWN:
220 //printf("V.29 Carrier down\n");
221 t4_end();
222 break;
223 default:
224 printf("V.29 Eh!\n");
225 break;
226 }
227 return;
228 }
229
230 end_of_page = t4_rx_put_bit(&t4_state, bit);
231 if (end_of_page)
232 {
233 t4_end();
234 printf("End of page detected\n");
235 }
236 //printf("V.29 Rx bit %d - %d\n", rx_bits++, bit);
237 }
238 /*- End of function --------------------------------------------------------*/
239
240 static void v27ter_put_bit(void *user_data, int bit)
241 {
242 if (bit < 0)
243 {
244 /* Special conditions */
245 switch (bit)
246 {
247 case PUTBIT_TRAINING_FAILED:
248 //printf("V.27ter Training failed\n");
249 break;
250 case PUTBIT_TRAINING_SUCCEEDED:
251 printf("V.27ter Training succeeded\n");
252 t4_begin();
253 break;
254 case PUTBIT_CARRIER_UP:
255 //printf("V.27ter Carrier up\n");
256 break;
257 case PUTBIT_CARRIER_DOWN:
258 //printf("V.27ter Carrier down\n");
259 break;
260 default:
261 printf("V.27ter Eh!\n");
262 break;
263 }
264 return;
265 }
266
267 printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);
268 }
269 /*- End of function --------------------------------------------------------*/
270
271 int main(int argc, char *argv[])
272 {
273 hdlc_rx_state_t hdlcrx;
274 fsk_rx_state_t fsk;
275 #if defined(ENABLE_V17)
276 v17_rx_state_t v17;
277 #endif
278 v29_rx_state_t v29;
279 v27ter_rx_state_t v27ter;
280 int16_t amp[SAMPLES_PER_CHUNK];
281 AFfilehandle inhandle;
282 int len;
283 const char *filename;
284
285 filename = "fax_samp.wav";
286
287 if (argc > 1)
288 filename = argv[1];
289
290 inhandle = afOpenFile(filename, "r", NULL);
291 if (inhandle == AF_NULL_FILEHANDLE)
292 {
293 fprintf(stderr, " Cannot open wave file '%s'\n", filename);
294 exit(2);
295 }
296 memset(&t30_dummy, 0, sizeof(t30_dummy));
297 span_log_init(&t30_dummy.logging, SPAN_LOG_FLOW, NULL);
298 span_log_set_protocol(&t30_dummy.logging, "T.30");
299
300 hdlc_rx_init(&hdlcrx, FALSE, FALSE, 1, hdlc_accept, NULL);
301 fsk_rx_init(&fsk, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &hdlcrx);
302 #if defined(ENABLE_V17)
303 v17_rx_init(&v17, 14400, v17_put_bit, NULL);
304 #endif
305 v29_rx_init(&v29, 9600, v29_put_bit, NULL);
306 v27ter_rx_init(&v27ter, 4800, v27ter_put_bit, NULL);
307 fsk_rx_signal_cutoff(&fsk, -45.0);
308 #if defined(ENABLE_V17)
309 v17_rx_signal_cutoff(&v17, -45.0);
310 #endif
311 v29_rx_signal_cutoff(&v29, -45.0);
312 v27ter_rx_signal_cutoff(&v27ter, -40.0);
313
314 //span_log_init(&v29.logging, SPAN_LOG_FLOW, NULL);
315 //span_log_set_protocol(&v29.logging, "V.29");
316 //span_log_set_level(&v29.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
317
318 if (t4_rx_init(&t4_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D))
319 {
320 printf("Failed to init\n");
321 exit(0);
322 }
323
324 for (;;)
325 {
326 len = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, SAMPLES_PER_CHUNK);
327 if (len < SAMPLES_PER_CHUNK)
328 break;
329 fsk_rx(&fsk, amp, len);
330 #if defined(ENABLE_V17)
331 v17_rx(&v17, amp, len);
332 #endif
333 v29_rx(&v29, amp, len);
334 v27ter_rx(&v27ter, amp, len);
335 }
336 t4_rx_end(&t4_state);
337
338 if (afCloseFile(inhandle) != 0)
339 {
340 fprintf(stderr, " Cannot close wave file '%s'\n", filename);
341 exit(2);
342 }
343 return 0;
344 }
345 /*- End of function --------------------------------------------------------*/
346 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.