~ubuntu-branches/ubuntu/trusty/iaxmodem/trusty

« back to all changes in this revision

Viewing changes to lib/spandsp/tests/fax_decode.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2007-05-15 09:43:53 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070515094353-bpr27hxvt6taxugb
Tags: 0.3.0~dfsg-1
* New upstream release.
  + Now supports V.17 reception; see changelog for details.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#define ENABLE_V17
 
2
 
2
3
/*
3
4
 * SpanDSP - a series of DSP components for telephony
4
5
 *
23
24
 * along with this program; if not, write to the Free Software
24
25
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26
 *
26
 
 * $Id: fax_decode.c,v 1.22 2006/11/19 14:07:27 steveu Exp $
 
27
 * $Id: fax_decode.c,v 1.28 2007/04/30 13:13:36 steveu Exp $
27
28
 */
28
29
 
29
30
/*! \page fax_decode_page FAX decoder
56
57
 
57
58
#define SAMPLES_PER_CHUNK   160
58
59
 
 
60
#define DISBIT1     0x01
 
61
#define DISBIT2     0x02
 
62
#define DISBIT3     0x04
 
63
#define DISBIT4     0x08
 
64
#define DISBIT5     0x10
 
65
#define DISBIT6     0x20
 
66
#define DISBIT7     0x40
 
67
#define DISBIT8     0x80
 
68
 
 
69
enum
 
70
{
 
71
    FAX_NONE,
 
72
    FAX_V27TER_RX,
 
73
    FAX_V29_RX,
 
74
    FAX_V17_RX
 
75
};
 
76
 
 
77
static const struct
 
78
{
 
79
    int bit_rate;
 
80
    int modem_type;
 
81
    int which;
 
82
    uint8_t dcs_code;
 
83
} fallback_sequence[] =
 
84
{
 
85
    {14400, T30_MODEM_V17_14400,    T30_SUPPORT_V17,    DISBIT6},
 
86
    {12000, T30_MODEM_V17_12000,    T30_SUPPORT_V17,    (DISBIT6 | DISBIT4)},
 
87
    { 9600, T30_MODEM_V17_9600,     T30_SUPPORT_V17,    (DISBIT6 | DISBIT3)},
 
88
    { 9600, T30_MODEM_V29_9600,     T30_SUPPORT_V29,    DISBIT3},
 
89
    { 7200, T30_MODEM_V17_7200,     T30_SUPPORT_V17,    (DISBIT6 | DISBIT4 | DISBIT3)},
 
90
    { 7200, T30_MODEM_V29_7200,     T30_SUPPORT_V29,    (DISBIT4 | DISBIT3)},
 
91
    { 4800, T30_MODEM_V27TER_4800,  T30_SUPPORT_V27TER, DISBIT4},
 
92
    { 2400, T30_MODEM_V27TER_2400,  T30_SUPPORT_V27TER, 0},
 
93
    {    0, 0, 0, 0}
 
94
};
 
95
 
59
96
int decode_test = FALSE;
60
 
 
61
97
int rx_bits = 0;
62
98
 
63
99
t30_state_t t30_dummy;
64
100
t4_state_t t4_state;
65
101
int t4_up = FALSE;
66
102
 
 
103
hdlc_rx_state_t hdlcrx;
 
104
 
 
105
int fast_trained = FAX_NONE;
 
106
 
 
107
uint8_t ecm_data[256][260];
 
108
int16_t ecm_len[256];
 
109
 
 
110
int line_encoding = T4_COMPRESSION_ITU_T4_2D;
 
111
int x_resolution = T4_X_RESOLUTION_R8;
 
112
int y_resolution = T4_Y_RESOLUTION_STANDARD;
 
113
int image_width = 1728;
 
114
int octets_per_ecm_frame = 256;
 
115
int error_correcting_mode = FALSE;
 
116
int current_fallback = 0;
 
117
 
67
118
static void print_frame(const char *io, const uint8_t *fr, int frlen)
68
119
{
69
120
    int i;
84
135
        if (t35_decode(&fr[3], frlen - 3, &country, &vendor, &model))
85
136
        {
86
137
            if (country)
87
 
                printf("The remote was made in '%s'\n", country);
 
138
                fprintf(stderr, "The remote was made in '%s'\n", country);
88
139
            if (vendor)
89
 
                printf("The remote was made by '%s'\n", vendor);
 
140
                fprintf(stderr, "The remote was made by '%s'\n", vendor);
90
141
            if (model)
91
 
                printf("The remote is a '%s'\n", model);
 
142
                fprintf(stderr, "The remote is a '%s'\n", model);
92
143
        }
93
144
    }
94
145
}
95
146
/*- End of function --------------------------------------------------------*/
96
147
 
 
148
static int find_fallback_entry(int dcs_code)
 
149
{
 
150
    int i;
 
151
 
 
152
    /* The table is short, and not searched often, so a brain-dead linear scan seems OK */
 
153
    for (i = 0;  fallback_sequence[i].bit_rate;  i++)
 
154
    {
 
155
        if (fallback_sequence[i].dcs_code == dcs_code)
 
156
            break;
 
157
    }
 
158
    if (fallback_sequence[i].bit_rate == 0)
 
159
        return -1;
 
160
    return i;
 
161
}
 
162
/*- End of function --------------------------------------------------------*/
 
163
 
 
164
static int check_rx_dcs(const uint8_t *msg, int len)
 
165
{
 
166
    static const int widths[3][4] =
 
167
    {
 
168
        { 864, 1024, 1216, -1}, /* R4 resolution - no longer used in recent versions of T.30 */
 
169
        {1728, 2048, 2432, -1}, /* R8 resolution */
 
170
        {3456, 4096, 4864, -1}  /* R16 resolution */
 
171
    };
 
172
    uint8_t dcs_frame[T30_MAX_DIS_DTC_DCS_LEN];
 
173
 
 
174
    /* Check DCS frame from remote */
 
175
    if (len < 6)
 
176
    {
 
177
        printf("Short DCS frame\n");
 
178
        return -1;
 
179
    }
 
180
 
 
181
    /* Make a local copy of the message, padded to the maximum possible length with zeros. This allows
 
182
       us to simply pick out the bits, without worrying about whether they were set from the remote side. */
 
183
    if (len > T30_MAX_DIS_DTC_DCS_LEN)
 
184
    {
 
185
        memcpy(dcs_frame, msg, T30_MAX_DIS_DTC_DCS_LEN);
 
186
    }
 
187
    else
 
188
    {
 
189
        memcpy(dcs_frame, msg, len);
 
190
        if (len < T30_MAX_DIS_DTC_DCS_LEN)
 
191
            memset(dcs_frame + len, 0, T30_MAX_DIS_DTC_DCS_LEN - len);
 
192
    }
 
193
 
 
194
    octets_per_ecm_frame = (dcs_frame[6] & DISBIT4)  ?  256  :  64;
 
195
    if ((dcs_frame[8] & DISBIT1))
 
196
        y_resolution = T4_Y_RESOLUTION_SUPERFINE;
 
197
    else if (dcs_frame[4] & DISBIT7)
 
198
        y_resolution = T4_Y_RESOLUTION_FINE;
 
199
    else
 
200
        y_resolution = T4_Y_RESOLUTION_STANDARD;
 
201
    image_width = widths[(dcs_frame[8] & DISBIT3)  ?  2  :  1][dcs_frame[5] & (DISBIT2 | DISBIT1)];
 
202
 
 
203
    /* Check which compression we will use. */
 
204
    if ((dcs_frame[6] & DISBIT7))
 
205
        line_encoding = T4_COMPRESSION_ITU_T6;
 
206
    else if ((dcs_frame[4] & DISBIT8))
 
207
        line_encoding = T4_COMPRESSION_ITU_T4_2D;
 
208
    else
 
209
        line_encoding = T4_COMPRESSION_ITU_T4_1D;
 
210
    printf("Selected compression %d\n", line_encoding);
 
211
 
 
212
    if ((current_fallback = find_fallback_entry(dcs_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3))) < 0)
 
213
        printf("Remote asked for a modem standard we do not support\n");
 
214
    error_correcting_mode = ((dcs_frame[6] & DISBIT3) != 0);
 
215
 
 
216
#if defined(ENABLE_V17)
 
217
    //v17_rx_restart(&v17, fallback_sequence[fallback_entry].bit_rate, FALSE);
 
218
#endif
 
219
    return 0;
 
220
}
 
221
/*- End of function --------------------------------------------------------*/
 
222
 
97
223
static void hdlc_accept(void *user_data, int ok, const uint8_t *msg, int len)
98
224
{
 
225
    int type;
 
226
    int frame_no;
 
227
    int i;
 
228
 
99
229
    if (len < 0)
100
230
    {
101
231
        /* Special conditions */
102
232
        switch (len)
103
233
        {
104
234
        case PUTBIT_CARRIER_UP:
105
 
            fprintf(stderr, "Slow carrier up\n");
 
235
            fprintf(stderr, "HDLC carrier up\n");
106
236
            break;
107
237
        case PUTBIT_CARRIER_DOWN:
108
 
            fprintf(stderr, "Slow carrier down\n");
 
238
            fprintf(stderr, "HDLC carrier down\n");
109
239
            break;
110
240
        case PUTBIT_FRAMING_OK:
 
241
            fprintf(stderr, "HDLC framing OK\n");
 
242
            break;
111
243
        case PUTBIT_ABORT:
112
244
            /* Just ignore these */
113
245
            break;
118
250
        return;
119
251
    }
120
252
    
121
 
    if (msg[0] != 0xFF  ||  !(msg[1] == 0x03  ||  msg[1] == 0x13))
122
 
    {
123
 
        fprintf(stderr, "Bad frame header - %02x %02x", msg[0], msg[1]);
124
 
        return;
125
 
    }
126
 
    print_frame("HDLC: ", msg, len);
 
253
    if (ok)
 
254
    {
 
255
        if (msg[0] != 0xFF  ||  !(msg[1] == 0x03  ||  msg[1] == 0x13))
 
256
        {
 
257
            fprintf(stderr, "Bad frame header - %02x %02x", msg[0], msg[1]);
 
258
            return;
 
259
        }
 
260
        print_frame("HDLC: ", msg, len);
 
261
        type = msg[2] & 0xFE;
 
262
        switch (type)
 
263
        {
 
264
        case T4_FCD:
 
265
            if (len <= 4 + 256)
 
266
            {
 
267
                frame_no = msg[3];
 
268
                /* Just store the actual image data, and record its length */
 
269
                memcpy(&ecm_data[frame_no][0], &msg[4], len - 4);
 
270
                ecm_len[frame_no] = (int16_t) (len - 4);
 
271
            }
 
272
            break;
 
273
        case T30_DCS:
 
274
            check_rx_dcs(msg, len);
 
275
            break;
 
276
        }
 
277
    }
 
278
    else
 
279
    {
 
280
        fprintf(stderr, "Bad HDLC frame ");
 
281
        for (i = 0;  i < len;  i++)
 
282
            fprintf(stderr, " %02x", msg[i]);
 
283
        fprintf(stderr, "\n");
 
284
    }
127
285
}
128
286
/*- End of function --------------------------------------------------------*/
129
287
 
130
288
static void t4_begin(void)
131
289
{
132
 
    t4_rx_set_rx_encoding(&t4_state, T4_COMPRESSION_ITU_T4_2D);
133
 
    t4_rx_set_x_resolution(&t4_state, T4_X_RESOLUTION_R8);
134
 
    t4_rx_set_y_resolution(&t4_state, T4_Y_RESOLUTION_STANDARD);
135
 
    t4_rx_set_image_width(&t4_state, 1728);
 
290
    int i;
 
291
 
 
292
    t4_rx_set_rx_encoding(&t4_state, line_encoding);
 
293
    t4_rx_set_x_resolution(&t4_state, x_resolution);
 
294
    t4_rx_set_y_resolution(&t4_state, y_resolution);
 
295
    t4_rx_set_image_width(&t4_state, image_width);
136
296
 
137
297
    t4_rx_start_page(&t4_state);
138
298
    t4_up = TRUE;
 
299
 
 
300
    for (i = 0;  i < 256;  i++)
 
301
        ecm_len[i] = -1;
139
302
}
140
303
/*- End of function --------------------------------------------------------*/
141
304
 
142
305
static void t4_end(void)
143
306
{
144
307
    t4_stats_t stats;
 
308
    int i;
145
309
 
146
310
    if (!t4_up)
147
311
        return;
148
312
    t4_rx_end_page(&t4_state);
149
313
    t4_get_transfer_statistics(&t4_state, &stats);
150
 
    printf("Pages = %d\n", stats.pages_transferred);
151
 
    printf("Image size = %dx%d\n", stats.width, stats.length);
152
 
    printf("Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution);
153
 
    printf("Bad rows = %d\n", stats.bad_rows);
154
 
    printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
 
314
    fprintf(stderr, "Pages = %d\n", stats.pages_transferred);
 
315
    fprintf(stderr, "Image size = %dx%d\n", stats.width, stats.length);
 
316
    fprintf(stderr, "Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution);
 
317
    fprintf(stderr, "Bad rows = %d\n", stats.bad_rows);
 
318
    fprintf(stderr, "Longest bad row run = %d\n", stats.longest_bad_row_run);
 
319
    for (i = 0;  i < 256;  i++)
 
320
        printf("%d", (ecm_len[i] < 0)  ?  0  :  1);
 
321
    printf("\n");
155
322
    t4_up = FALSE;
156
323
}
157
324
/*- End of function --------------------------------------------------------*/
158
325
 
 
326
static void v21_put_bit(void *user_data, int bit)
 
327
{
 
328
    if (bit < 0)
 
329
    {
 
330
        /* Special conditions */
 
331
        switch (bit)
 
332
        {
 
333
        case PUTBIT_TRAINING_FAILED:
 
334
            fprintf(stderr, "V.21 Training failed\n");
 
335
            break;
 
336
        case PUTBIT_TRAINING_SUCCEEDED:
 
337
            fprintf(stderr, "V.21 Training succeeded\n");
 
338
            t4_begin();
 
339
            break;
 
340
        case PUTBIT_CARRIER_UP:
 
341
            fprintf(stderr, "V.21 Carrier up\n");
 
342
            break;
 
343
        case PUTBIT_CARRIER_DOWN:
 
344
            fprintf(stderr, "V.21 Carrier down\n");
 
345
            t4_end();
 
346
            break;
 
347
        default:
 
348
            fprintf(stderr, "V.21 Eh!\n");
 
349
            break;
 
350
        }
 
351
        return;
 
352
    }
 
353
    if (fast_trained == FAX_NONE)
 
354
        hdlc_rx_put_bit(&hdlcrx, bit);
 
355
    //printf("V.21 Rx bit %d - %d\n", rx_bits++, bit);
 
356
}
 
357
/*- End of function --------------------------------------------------------*/
 
358
 
159
359
#if defined(ENABLE_V17)
160
360
static void v17_put_bit(void *user_data, int bit)
161
361
{
162
 
    int end_of_page;
163
 
    
164
362
    if (bit < 0)
165
363
    {
166
364
        /* Special conditions */
167
365
        switch (bit)
168
366
        {
169
367
        case PUTBIT_TRAINING_FAILED:
170
 
            //printf("V.17 Training failed\n");
 
368
            fprintf(stderr, "V.17 Training failed\n");
171
369
            break;
172
370
        case PUTBIT_TRAINING_SUCCEEDED:
173
 
            printf("V.17 Training succeeded\n");
 
371
            fprintf(stderr, "V.17 Training succeeded\n");
 
372
            fast_trained = FAX_V17_RX;
174
373
            t4_begin();
175
374
            break;
176
375
        case PUTBIT_CARRIER_UP:
177
 
            //printf("V.17 Carrier up\n");
 
376
            fprintf(stderr, "V.17 Carrier up\n");
178
377
            break;
179
378
        case PUTBIT_CARRIER_DOWN:
180
 
            //printf("V.17 Carrier down\n");
 
379
            fprintf(stderr, "V.17 Carrier down\n");
181
380
            t4_end();
 
381
            if (fast_trained == FAX_V17_RX)
 
382
                fast_trained = FAX_NONE;
182
383
            break;
183
384
        default:
184
 
            printf("V.17 Eh!\n");
 
385
            fprintf(stderr, "V.17 Eh!\n");
185
386
            break;
186
387
        }
187
388
        return;
188
389
    }
189
 
 
190
 
    end_of_page = t4_rx_putbit(&t4_state, bit);
191
 
    if (end_of_page)
192
 
    {
193
 
        t4_end();
194
 
        printf("End of page detected\n");
 
390
    if (error_correcting_mode)
 
391
    {
 
392
        hdlc_rx_put_bit(&hdlcrx, bit);
 
393
    }
 
394
    else
 
395
    {
 
396
        if (t4_rx_put_bit(&t4_state, bit))
 
397
        {
 
398
            t4_end();
 
399
            fprintf(stderr, "End of page detected\n");
 
400
        }
195
401
    }
196
402
    //printf("V.17 Rx bit %d - %d\n", rx_bits++, bit);
197
403
}
200
406
 
201
407
static void v29_put_bit(void *user_data, int bit)
202
408
{
203
 
    int end_of_page;
204
 
    
205
409
    if (bit < 0)
206
410
    {
207
411
        /* Special conditions */
208
412
        switch (bit)
209
413
        {
210
414
        case PUTBIT_TRAINING_FAILED:
211
 
            //printf("V.29 Training failed\n");
 
415
            //fprintf(stderr, "V.29 Training failed\n");
212
416
            break;
213
417
        case PUTBIT_TRAINING_SUCCEEDED:
214
 
            printf("V.29 Training succeeded\n");
 
418
            fprintf(stderr, "V.29 Training succeeded\n");
 
419
            fast_trained = FAX_V29_RX;
215
420
            t4_begin();
216
421
            break;
217
422
        case PUTBIT_CARRIER_UP:
218
 
            //printf("V.29 Carrier up\n");
 
423
            //fprintf(stderr, "V.29 Carrier up\n");
219
424
            break;
220
425
        case PUTBIT_CARRIER_DOWN:
221
 
            //printf("V.29 Carrier down\n");
 
426
            //fprintf(stderr, "V.29 Carrier down\n");
222
427
            t4_end();
 
428
            if (fast_trained == FAX_V29_RX)
 
429
                fast_trained = FAX_NONE;
223
430
            break;
224
431
        default:
225
 
            printf("V.29 Eh!\n");
 
432
            fprintf(stderr, "V.29 Eh!\n");
226
433
            break;
227
434
        }
228
435
        return;
229
436
    }
230
437
 
231
 
    end_of_page = t4_rx_put_bit(&t4_state, bit);
232
 
    if (end_of_page)
233
 
    {
234
 
        t4_end();
235
 
        printf("End of page detected\n");
 
438
    if (error_correcting_mode)
 
439
    {
 
440
        hdlc_rx_put_bit(&hdlcrx, bit);
 
441
    }
 
442
    else
 
443
    {
 
444
        if (t4_rx_put_bit(&t4_state, bit))
 
445
        {
 
446
            t4_end();
 
447
            fprintf(stderr, "End of page detected\n");
 
448
        }
236
449
    }
237
450
    //printf("V.29 Rx bit %d - %d\n", rx_bits++, bit);
238
451
}
246
459
        switch (bit)
247
460
        {
248
461
        case PUTBIT_TRAINING_FAILED:
249
 
            //printf("V.27ter Training failed\n");
 
462
            //fprintf(stderr, "V.27ter Training failed\n");
250
463
            break;
251
464
        case PUTBIT_TRAINING_SUCCEEDED:
252
 
            printf("V.27ter Training succeeded\n");
 
465
            fprintf(stderr, "V.27ter Training succeeded\n");
 
466
            fast_trained = FAX_V27TER_RX;
253
467
            t4_begin();
254
468
            break;
255
469
        case PUTBIT_CARRIER_UP:
256
 
            //printf("V.27ter Carrier up\n");
 
470
            //fprintf(stderr, "V.27ter Carrier up\n");
257
471
            break;
258
472
        case PUTBIT_CARRIER_DOWN:
259
 
            //printf("V.27ter Carrier down\n");
 
473
            //fprintf(stderr, "V.27ter Carrier down\n");
 
474
            if (fast_trained == FAX_V27TER_RX)
 
475
                fast_trained = FAX_NONE;
260
476
            break;
261
477
        default:
262
 
            printf("V.27ter Eh!\n");
 
478
            fprintf(stderr, "V.27ter Eh!\n");
263
479
            break;
264
480
        }
265
481
        return;
266
482
    }
267
483
 
268
 
    printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);
 
484
    if (error_correcting_mode)
 
485
    {
 
486
        hdlc_rx_put_bit(&hdlcrx, bit);
 
487
    }
 
488
    else
 
489
    {
 
490
        if (t4_rx_put_bit(&t4_state, bit))
 
491
        {
 
492
            t4_end();
 
493
            fprintf(stderr, "End of page detected\n");
 
494
        }
 
495
    }
 
496
    //printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);
269
497
}
270
498
/*- End of function --------------------------------------------------------*/
271
499
 
272
500
int main(int argc, char *argv[])
273
501
{
274
 
    hdlc_rx_state_t hdlcrx;
275
502
    fsk_rx_state_t fsk;
276
503
#if defined(ENABLE_V17)
277
504
    v17_rx_state_t v17;
298
525
    span_log_init(&t30_dummy.logging, SPAN_LOG_FLOW, NULL);
299
526
    span_log_set_protocol(&t30_dummy.logging, "T.30");
300
527
 
301
 
    hdlc_rx_init(&hdlcrx, FALSE, FALSE, 1, hdlc_accept, NULL);
302
 
    fsk_rx_init(&fsk, &preset_fsk_specs[FSK_V21CH2], TRUE, 0, (put_bit_func_t) hdlc_rx_put_bit, &hdlcrx);
 
528
    hdlc_rx_init(&hdlcrx, FALSE, TRUE, 5, hdlc_accept, NULL);
 
529
    fsk_rx_init(&fsk, &preset_fsk_specs[FSK_V21CH2], TRUE, 0, v21_put_bit, NULL);
303
530
#if defined(ENABLE_V17)
304
531
    v17_rx_init(&v17, 14400, v17_put_bit, NULL);
305
532
#endif
306
533
    v29_rx_init(&v29, 9600, v29_put_bit, NULL);
307
534
    v27ter_rx_init(&v27ter, 4800, v27ter_put_bit, NULL);
308
 
    fsk_rx_signal_cutoff(&fsk, -45.0);
 
535
    fsk_rx_signal_cutoff(&fsk, -45.5);
309
536
#if defined(ENABLE_V17)
310
 
    v17_rx_signal_cutoff(&v17, -45.0);
 
537
    v17_rx_signal_cutoff(&v17, -45.5);
311
538
#endif
312
 
    v29_rx_signal_cutoff(&v29, -45.0);
 
539
    v29_rx_signal_cutoff(&v29, -45.5);
313
540
    v27ter_rx_signal_cutoff(&v27ter, -40.0);
314
541
 
315
 
    //span_log_init(&v29.logging, SPAN_LOG_FLOW, NULL);
316
 
    //span_log_set_protocol(&v29.logging, "V.29");
317
 
    //span_log_set_level(&v29.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
 
542
#if defined(ENABLE_V17)
 
543
    span_log_init(&v17.logging, SPAN_LOG_FLOW, NULL);
 
544
    span_log_set_protocol(&v17.logging, "V.17");
 
545
    span_log_set_level(&v17.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
 
546
#endif
318
547
 
319
548
    if (t4_rx_init(&t4_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D))
320
549
    {
321
 
        printf("Failed to init\n");
 
550
        fprintf(stderr, "Failed to init\n");
322
551
        exit(0);
323
552
    }
324
553