diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spandsp-0.0.3/spandsp-0.0.3/tests/fax_decode.c	Fri Jun 25 16:00:21 2010 +0200
@@ -0,0 +1,346 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * fax_decode.c - a simple FAX audio decoder
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2005 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: fax_decode.c,v 1.22 2006/11/19 14:07:27 steveu Exp $
+ */
+
+/*! \page fax_decode_page FAX decoder
+\section fax_decode_page_sec_1 What does it do?
+???.
+
+\section fax_decode_tests_page_sec_2 How does it work?
+???.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if defined(HAVE_TGMATH_H)
+#include <tgmath.h>
+#endif
+#if defined(HAVE_MATH_H)
+#include <math.h>
+#endif
+#include <assert.h>
+#include <audiofile.h>
+#include <tiffio.h>
+
+#include "spandsp.h"
+
+#define SAMPLES_PER_CHUNK   160
+
+int decode_test = FALSE;
+
+int rx_bits = 0;
+
+t30_state_t t30_dummy;
+t4_state_t t4_state;
+int t4_up = FALSE;
+
+static void print_frame(const char *io, const uint8_t *fr, int frlen)
+{
+    int i;
+    int type;
+    const char *country;
+    const char *vendor;
+    const char *model;
+    
+    fprintf(stderr, "%s %s:", io, t30_frametype(fr[2]));
+    for (i = 2;  i < frlen;  i++)
+        fprintf(stderr, " %02x", fr[i]);
+    fprintf(stderr, "\n");
+    type = fr[2] & 0xFE;
+    if (type == T30_DIS  ||  type == T30_DTC  ||  type == T30_DCS)
+        t30_decode_dis_dtc_dcs(&t30_dummy, fr, frlen);
+    if (type == T30_NSF)
+    {
+        if (t35_decode(&fr[3], frlen - 3, &country, &vendor, &model))
+        {
+            if (country)
+                printf("The remote was made in '%s'\n", country);
+            if (vendor)
+                printf("The remote was made by '%s'\n", vendor);
+            if (model)
+                printf("The remote is a '%s'\n", model);
+        }
+    }
+}
+/*- End of function --------------------------------------------------------*/
+
+static void hdlc_accept(void *user_data, int ok, const uint8_t *msg, int len)
+{
+    if (len < 0)
+    {
+        /* Special conditions */
+        switch (len)
+        {
+        case PUTBIT_CARRIER_UP:
+            fprintf(stderr, "Slow carrier up\n");
+            break;
+        case PUTBIT_CARRIER_DOWN:
+            fprintf(stderr, "Slow carrier down\n");
+            break;
+        case PUTBIT_FRAMING_OK:
+        case PUTBIT_ABORT:
+            /* Just ignore these */
+            break;
+        default:
+            fprintf(stderr, "Unexpected HDLC special length - %d!\n", len);
+            break;
+        }
+        return;
+    }
+    
+    if (msg[0] != 0xFF  ||  !(msg[1] == 0x03  ||  msg[1] == 0x13))
+    {
+        fprintf(stderr, "Bad frame header - %02x %02x", msg[0], msg[1]);
+        return;
+    }
+    print_frame("HDLC: ", msg, len);
+}
+/*- End of function --------------------------------------------------------*/
+
+static void t4_begin(void)
+{
+    t4_rx_set_rx_encoding(&t4_state, T4_COMPRESSION_ITU_T4_2D);
+    t4_rx_set_x_resolution(&t4_state, T4_X_RESOLUTION_R8);
+    t4_rx_set_y_resolution(&t4_state, T4_Y_RESOLUTION_STANDARD);
+    t4_rx_set_image_width(&t4_state, 1728);
+
+    t4_rx_start_page(&t4_state);
+    t4_up = TRUE;
+}
+/*- End of function --------------------------------------------------------*/
+
+static void t4_end(void)
+{
+    t4_stats_t stats;
+
+    if (!t4_up)
+        return;
+    t4_rx_end_page(&t4_state);
+    t4_get_transfer_statistics(&t4_state, &stats);
+    printf("Pages = %d\n", stats.pages_transferred);
+    printf("Image size = %dx%d\n", stats.width, stats.length);
+    printf("Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution);
+    printf("Bad rows = %d\n", stats.bad_rows);
+    printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
+    t4_up = FALSE;
+}
+/*- End of function --------------------------------------------------------*/
+
+#if defined(ENABLE_V17)
+static void v17_put_bit(void *user_data, int bit)
+{
+    int end_of_page;
+    
+    if (bit < 0)
+    {
+        /* Special conditions */
+        switch (bit)
+        {
+        case PUTBIT_TRAINING_FAILED:
+            //printf("V.17 Training failed\n");
+            break;
+        case PUTBIT_TRAINING_SUCCEEDED:
+            printf("V.17 Training succeeded\n");
+            t4_begin();
+            break;
+        case PUTBIT_CARRIER_UP:
+            //printf("V.17 Carrier up\n");
+            break;
+        case PUTBIT_CARRIER_DOWN:
+            //printf("V.17 Carrier down\n");
+            t4_end();
+            break;
+        default:
+            printf("V.17 Eh!\n");
+            break;
+        }
+        return;
+    }
+
+    end_of_page = t4_rx_putbit(&t4_state, bit);
+    if (end_of_page)
+    {
+        t4_end();
+        printf("End of page detected\n");
+    }
+    //printf("V.17 Rx bit %d - %d\n", rx_bits++, bit);
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+static void v29_put_bit(void *user_data, int bit)
+{
+    int end_of_page;
+    
+    if (bit < 0)
+    {
+        /* Special conditions */
+        switch (bit)
+        {
+        case PUTBIT_TRAINING_FAILED:
+            //printf("V.29 Training failed\n");
+            break;
+        case PUTBIT_TRAINING_SUCCEEDED:
+            printf("V.29 Training succeeded\n");
+            t4_begin();
+            break;
+        case PUTBIT_CARRIER_UP:
+            //printf("V.29 Carrier up\n");
+            break;
+        case PUTBIT_CARRIER_DOWN:
+            //printf("V.29 Carrier down\n");
+            t4_end();
+            break;
+        default:
+            printf("V.29 Eh!\n");
+            break;
+        }
+        return;
+    }
+
+    end_of_page = t4_rx_put_bit(&t4_state, bit);
+    if (end_of_page)
+    {
+        t4_end();
+        printf("End of page detected\n");
+    }
+    //printf("V.29 Rx bit %d - %d\n", rx_bits++, bit);
+}
+/*- End of function --------------------------------------------------------*/
+
+static void v27ter_put_bit(void *user_data, int bit)
+{
+    if (bit < 0)
+    {
+        /* Special conditions */
+        switch (bit)
+        {
+        case PUTBIT_TRAINING_FAILED:
+            //printf("V.27ter Training failed\n");
+            break;
+        case PUTBIT_TRAINING_SUCCEEDED:
+            printf("V.27ter Training succeeded\n");
+            t4_begin();
+            break;
+        case PUTBIT_CARRIER_UP:
+            //printf("V.27ter Carrier up\n");
+            break;
+        case PUTBIT_CARRIER_DOWN:
+            //printf("V.27ter Carrier down\n");
+            break;
+        default:
+            printf("V.27ter Eh!\n");
+            break;
+        }
+        return;
+    }
+
+    printf("V.27ter Rx bit %d - %d\n", rx_bits++, bit);
+}
+/*- End of function --------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+    hdlc_rx_state_t hdlcrx;
+    fsk_rx_state_t fsk;
+#if defined(ENABLE_V17)
+    v17_rx_state_t v17;
+#endif
+    v29_rx_state_t v29;
+    v27ter_rx_state_t v27ter;
+    int16_t amp[SAMPLES_PER_CHUNK];
+    AFfilehandle inhandle;
+    int len;
+    const char *filename;
+    
+    filename = "fax_samp.wav";
+
+    if (argc > 1)
+        filename = argv[1];
+
+    inhandle = afOpenFile(filename, "r", NULL);
+    if (inhandle == AF_NULL_FILEHANDLE)
+    {
+        fprintf(stderr, "    Cannot open wave file '%s'\n", filename);
+        exit(2);
+    }
+    memset(&t30_dummy, 0, sizeof(t30_dummy));
+    span_log_init(&t30_dummy.logging, SPAN_LOG_FLOW, NULL);
+    span_log_set_protocol(&t30_dummy.logging, "T.30");
+
+    hdlc_rx_init(&hdlcrx, FALSE, FALSE, 1, hdlc_accept, NULL);
+    fsk_rx_init(&fsk, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, &hdlcrx);
+#if defined(ENABLE_V17)
+    v17_rx_init(&v17, 14400, v17_put_bit, NULL);
+#endif
+    v29_rx_init(&v29, 9600, v29_put_bit, NULL);
+    v27ter_rx_init(&v27ter, 4800, v27ter_put_bit, NULL);
+    fsk_rx_signal_cutoff(&fsk, -45.0);
+#if defined(ENABLE_V17)
+    v17_rx_signal_cutoff(&v17, -45.0);
+#endif
+    v29_rx_signal_cutoff(&v29, -45.0);
+    v27ter_rx_signal_cutoff(&v27ter, -40.0);
+
+    //span_log_init(&v29.logging, SPAN_LOG_FLOW, NULL);
+    //span_log_set_protocol(&v29.logging, "V.29");
+    //span_log_set_level(&v29.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
+
+    if (t4_rx_init(&t4_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D))
+    {
+        printf("Failed to init\n");
+        exit(0);
+    }
+        
+    for (;;)
+    {
+        len = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, SAMPLES_PER_CHUNK);
+        if (len < SAMPLES_PER_CHUNK)
+            break;
+        fsk_rx(&fsk, amp, len);
+#if defined(ENABLE_V17)
+        v17_rx(&v17, amp, len);
+#endif
+        v29_rx(&v29, amp, len);
+        v27ter_rx(&v27ter, amp, len);
+    }
+    t4_rx_end(&t4_state);
+
+    if (afCloseFile(inhandle) != 0)
+    {
+        fprintf(stderr, "    Cannot close wave file '%s'\n", filename);
+        exit(2);
+    }
+    return  0;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/

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