static int power_surge_detector_file_test(const char *file)
{
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int inframes;
    power_surge_detector_state_t *sig;
    int i;
    int16_t amp[8000];
    int16_t amp_out[2*8000];
    int sample;
    float signal_power;
    int32_t signal_level;
    int signal_present;
    int prev_signal_present;

    if ((inhandle = sf_open_telephony_read(file, 1)) == NULL)
    {
        printf("    Cannot open speech file '%s'\n", file);
        exit(2);
    }

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    sig = power_surge_detector_init(NULL, -50.0f, 6.0f);
    prev_signal_present = FALSE;

    sample = 0;
    while ((inframes = sf_readf_short(inhandle, amp, 8000)))
    {
        for (i = 0;  i < inframes;  i++)
        {
            signal_level = power_surge_detector(sig, amp[i]);
            signal_present = (signal_level != 0);
            if (prev_signal_present != signal_present)
            {
                signal_power = power_surge_detector_current_dbm0(sig);
                if (signal_present)
                    printf("On at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
                else
                    printf("Off at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
                prev_signal_present = signal_present;
            }
            amp_out[2*i] = amp[i];
            amp_out[2*i + 1] = signal_present*5000;
        }
        sf_writef_short(outhandle, amp_out, inframes);
        sample += inframes;
    }
    sf_close(inhandle);
    sf_close(outhandle);
    return 0;
}
int main(int argc, char *argv[])
{
    r2_mf_tx_state_t gen;
    int16_t amp[1000];
    int len;
    SNDFILE *outhandle;
    int digit;
    const char *digits = "0123456789BCDEF";

    if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    r2_mf_tx_init(&gen, FALSE);
    for (digit = 0;  digits[digit];  digit++)
    {
        r2_mf_tx_put(&gen, digits[digit]);
        len = r2_mf_tx(&gen, amp, 1000);
        printf("Generated %d samples of %c\n", len, digits[digit]);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
        r2_mf_tx_put(&gen, 0);
        len = r2_mf_tx(&gen, amp, 1000);
        printf("Generated %d samples\n", len);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
    }

    r2_mf_tx_init(&gen, TRUE);
    for (digit = 0;  digits[digit];  digit++)
    {
        r2_mf_tx_put(&gen, digits[digit]);
        len = r2_mf_tx(&gen, amp, 1000);
        printf("Generated %d samples of %c\n", len, digits[digit]);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
        r2_mf_tx_put(&gen, 0);
        len = r2_mf_tx(&gen, amp, 1000);
        printf("Generated %d samples\n", len);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
    }

    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
        exit (2);
    }

    return  0;
}
int main(int argc, char *argv[])
{
    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
#if defined(HAVE_LIBXML2)
    get_tone_set("../spandsp/global-tones.xml", (argc > 1)  ?  argv[1]  :  "hk");
#endif
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    printf("Done\n");
    return 0;
}
Beispiel #4
0
static void complexify_tests(void)
{
    complexify_state_t *s;
    complexf_t cc;
    int16_t amp;
    int i;
    SNDFILE *outhandle;
    int outframes;
    int16_t out[40000];
    awgn_state_t noise1;

    if ((outhandle = sf_open_telephony_write(OUT_FILE_COMPLEXIFY, 2)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_COMPLEXIFY);
        exit(2);
    }
    awgn_init_dbm0(&noise1, 1234567, -10.0f);
    s = complexify_init();
    for (i = 0;  i < 20000;  i++)
    {
        amp = awgn(&noise1);
        cc = complexify(s, amp);
        out[2*i] = cc.re;
        out[2*i + 1] = cc.im;
    }
    awgn_release(&noise1);
    complexify_free(s);
    outframes = sf_writef_short(outhandle, out, 20000);
    if (outframes != 20000)
    {
        fprintf(stderr, "    Error writing audio file\n");
        exit(2);
    }
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_COMPLEXIFY);
        exit(2);
    }
}
Beispiel #5
0
int main(int argc, char *argv[])
{
    int16_t amp[2][BLOCK_LEN];
    int16_t model_amp[2][BLOCK_LEN];
    int16_t out_amp[2*BLOCK_LEN];
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int outframes;
    int samples;
    int samples2;
    int i;
    int j;
    int test_bps;
    int line_model_no;
    int bits_per_test;
    int noise_level;
    int signal_level;
    int channel_codec;
    int rbs_pattern;
    int guard_tone_option;
    int opt;
    bool log_audio;

    channel_codec = MUNGE_CODEC_NONE;
    rbs_pattern = 0;
    test_bps = 2400;
    line_model_no = 0;
    decode_test_file = NULL;
    noise_level = -70;
    signal_level = -13;
    bits_per_test = 50000;
    guard_tone_option = V22BIS_GUARD_TONE_1800HZ;
    log_audio = false;
    while ((opt = getopt(argc, argv, "b:B:c:d:gG:lm:n:r:s:")) != -1)
    {
        switch (opt)
        {
        case 'b':
            test_bps = atoi(optarg);
            if (test_bps != 2400  &&  test_bps != 1200)
            {
                fprintf(stderr, "Invalid bit rate specified\n");
                exit(2);
            }
            break;
        case 'B':
            bits_per_test = atoi(optarg);
            break;
        case 'c':
            channel_codec = atoi(optarg);
            break;
        case 'd':
            decode_test_file = optarg;
            break;
        case 'g':
#if defined(ENABLE_GUI)
            use_gui = true;
#else
            fprintf(stderr, "Graphical monitoring not available\n");
            exit(2);
#endif
            break;
        case 'G':
            guard_tone_option = atoi(optarg);
            break;
        case 'l':
            log_audio = true;
            break;
        case 'm':
            line_model_no = atoi(optarg);
            break;
        case 'n':
            noise_level = atoi(optarg);
            break;
        case 'r':
            rbs_pattern = atoi(optarg);
            break;
        case 's':
            signal_level = atoi(optarg);
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }
    inhandle = NULL;
    if (decode_test_file)
    {
        /* We will decode the audio from a file. */
        if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }

    outhandle = NULL;
    if (log_audio)
    {
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }
    memset(endpoint, 0, sizeof(endpoint));

    for (i = 0;  i < 2;  i++)
    {
        endpoint[i].v22bis = v22bis_init(NULL, test_bps, guard_tone_option, (i == 0), v22bis_getbit, &endpoint[i], v22bis_putbit, &endpoint[i]);
        v22bis_tx_power(endpoint[i].v22bis, signal_level);
        /* Move the carrier off a bit */
        endpoint[i].v22bis->tx.carrier_phase_rate = dds_phase_ratef((i == 0)  ?  1207.0f  :  2407.0f);
        v22bis_rx_set_qam_report_handler(endpoint[i].v22bis, qam_report, (void *) &endpoint[i]);
        span_log_set_level(&endpoint[i].v22bis->logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
        span_log_set_tag(&endpoint[i].v22bis->logging, (i == 0)  ?  "caller"  :  "answerer");
        endpoint[i].smooth_power = 0.0f;
        endpoint[i].symbol_no = 0;
        bert_init(&endpoint[i].bert_tx, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
        bert_init(&endpoint[i].bert_rx, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
        bert_set_report(&endpoint[i].bert_rx, 10000, reporter, &endpoint[i]);
    }

#if defined(ENABLE_GUI)
    if (use_gui)
    {
        endpoint[0].qam_monitor = qam_monitor_init(6.0f, V22BIS_CONSTELLATION_SCALING_FACTOR, "Calling modem");
        endpoint[1].qam_monitor = qam_monitor_init(6.0f, V22BIS_CONSTELLATION_SCALING_FACTOR, "Answering modem");
    }
#endif
    if ((model = both_ways_line_model_init(line_model_no,
                                           (float) noise_level,
                                           -15.0f,
                                           -15.0f,
                                           line_model_no,
                                           (float) noise_level,
                                           -15.0f,
                                           -15.0f,
                                           channel_codec,
                                           rbs_pattern)) == NULL)
    {
        fprintf(stderr, "    Failed to create line model\n");
        exit(2);
    }
    samples = 0;
    for (;;)
    {
        for (i = 0;  i < 2;  i++)
        {
            samples = v22bis_tx(endpoint[i].v22bis, amp[i], BLOCK_LEN);
#if defined(ENABLE_GUI)
            if (use_gui)
                qam_monitor_update_audio_level(endpoint[i].qam_monitor, amp[i], samples);
#endif
            if (samples == 0)
            {
                /* Note that we might get a few bad bits as the carrier shuts down. */
                bert_result(&endpoint[i].bert_rx, &endpoint[i].latest_results);

                bert_init(&endpoint[i].bert_tx, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
                bert_init(&endpoint[i].bert_rx, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
                bert_set_report(&endpoint[i].bert_rx, 10000, reporter, &endpoint[i]);

                printf("Restarting on zero output\n");
                v22bis_restart(endpoint[i].v22bis, test_bps);
            }
        }

#if 1
        both_ways_line_model(model,
                             model_amp[0],
                             amp[0],
                             model_amp[1],
                             amp[1],
                             samples);
#else
        vec_copyi16(model_amp[0], amp[0], samples);
        vec_copyi16(model_amp[1], amp[1], samples);
#endif
        if (decode_test_file)
        {
            samples2 = sf_readf_short(inhandle, model_amp[0], samples);
            if (samples2 != samples)
                break;
        }
        for (i = 0;  i < 2;  i++)
        {
            span_log_bump_samples(&endpoint[i].v22bis->logging, samples);
            v22bis_rx(endpoint[i ^ 1].v22bis, model_amp[i], samples);
            for (j = 0;  j < samples;  j++)
                out_amp[2*j + i] = model_amp[i][j];
            for (  ;  j < BLOCK_LEN;  j++)
                out_amp[2*j + i] = 0;
        }

        if (log_audio)
        {
            outframes = sf_writef_short(outhandle, out_amp, BLOCK_LEN);
            if (outframes != BLOCK_LEN)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
        }
    }
#if defined(ENABLE_GUI)
    if (use_gui)
        qam_wait_to_end(endpoint[0].qam_monitor);
#endif
    if (decode_test_file)
    {
        if (sf_close_telephony(inhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    if (log_audio)
    {
        if (sf_close_telephony(outhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }
    return 0;
}
int main(int argc, char *argv[])
{
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int outframes;
    int opt;
    int samples;
    int len2;
    int len3;
    int basic_tests;
    int law;
    int encode;
    int decode;
    int file;
    const char *in_file;
    const char *out_file;
    g711_state_t *enc_state;
    g711_state_t *dec_state;
    int16_t indata[BLOCK_LEN];
    int16_t outdata[BLOCK_LEN];
    uint8_t g711data[BLOCK_LEN];

    basic_tests = TRUE;
    law = G711_ALAW;
    encode = FALSE;
    decode = FALSE;
    in_file = NULL;
    out_file = NULL;
    while ((opt = getopt(argc, argv, "ad:e:l:u")) != -1)
    {
        switch (opt)
        {
        case 'a':
            law = G711_ALAW;
            basic_tests = FALSE;
            break;
        case 'd':
            in_file = optarg;
            basic_tests = FALSE;
            decode = TRUE;
            break;
        case 'e':
            in_file = optarg;
            basic_tests = FALSE;
            encode = TRUE;
            break;
        case 'l':
            out_file = optarg;
            break;
        case 'u':
            law = G711_ULAW;
            basic_tests = FALSE;
            break;
        default:
            //usage();
            exit(2);
        }
    }

    if (basic_tests)
    {
        compliance_tests(TRUE);
    }
    else
    {
        if (!decode  &&  !encode)
        {
            decode =
                encode = TRUE;
        }
        if (in_file == NULL)
        {
            in_file = (encode)  ?  IN_FILE_NAME  :  ENCODED_FILE_NAME;
        }
        if (out_file == NULL)
        {
            out_file = (decode)  ?  OUT_FILE_NAME  :  ENCODED_FILE_NAME;
        }
        inhandle = NULL;
        outhandle = NULL;
        file = -1;
        enc_state = NULL;
        dec_state = NULL;
        if (encode)
        {
            if ((inhandle = sf_open_telephony_read(in_file, 1)) == NULL)
            {
                fprintf(stderr, "    Cannot open audio file '%s'\n", in_file);
                exit(2);
            }
            enc_state = g711_init(NULL, law);
        }
        else
        {
            if ((file = open(in_file, O_RDONLY)) < 0)
            {
                fprintf(stderr, "    Failed to open '%s'\n", in_file);
                exit(2);
            }
        }
        if (decode)
        {
            if ((outhandle = sf_open_telephony_write(out_file, 1)) == NULL)
            {
                fprintf(stderr, "    Cannot create audio file '%s'\n", out_file);
                exit(2);
            }
            dec_state = g711_init(NULL, law);
        }
        else
        {
            if ((file = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
            {
                fprintf(stderr, "    Failed to open '%s'\n", out_file);
                exit(2);
            }
        }
        for (;;)
        {
            if (encode)
            {
                samples = sf_readf_short(inhandle, indata, BLOCK_LEN);
                if (samples <= 0)
                    break;
                len2 = g711_encode(enc_state, g711data, indata, samples);
            }
            else
            {
                len2 = read(file, g711data, BLOCK_LEN);
                if (len2 <= 0)
                    break;
            }
            if (decode)
            {
                len3 = g711_decode(dec_state, outdata, g711data, len2);
                outframes = sf_writef_short(outhandle, outdata, len3);
                if (outframes != len3)
                {
                    fprintf(stderr, "    Error writing audio file\n");
                    exit(2);
                }
            }
            else
            {
                len3 = write(file, g711data, len2);
                if (len3 <= 0)
                    break;
            }
        }
        if (encode)
        {
            if (sf_close_telephony(inhandle))
            {
                fprintf(stderr, "    Cannot close audio file '%s'\n", IN_FILE_NAME);
                exit(2);
            }
        }
        else
        {
            close(file);
        }
        if (decode)
        {
            if (sf_close_telephony(outhandle))
            {
                fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
                exit(2);
            }
        }
        else
        {
            close(file);
        }
        printf("'%s' translated to '%s' using %s.\n", in_file, out_file, (law == G711_ALAW)  ?  "A-law"  :  "u-law");
    }
    return 0;
}
static int t30_tests(int t38_mode, int use_ecm, int use_gui, int log_audio, int test_sending, int g1050_model_no, int g1050_speed_pattern_no)
{
    t38_terminal_state_t *t38_state;
    fax_state_t *fax_state;
    uint8_t msg[1024];
    char buf[1024];
    int len;
    int msg_len;
    int t30_len;
    int t31_len;
    int t38_version;
    int without_pacing;
    int use_tep;
    int seq_no;
    double tx_when;
    double rx_when;
    t30_state_t *t30;
    t38_core_state_t *t38_core;
    logging_state_t *logging;
    int k;
    int outframes;
    int ret;
    int16_t t30_amp[SAMPLES_PER_CHUNK];
    int16_t t31_amp[SAMPLES_PER_CHUNK];
    int16_t silence[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    SNDFILE *wave_handle;
    SNDFILE *in_handle;
    at_state_t *at_state;
#if defined(WIN32)
	DWORD read_bytes;
	OVERLAPPED o;
#endif

    /* Test the T.31 modem against the full FAX machine in spandsp */
    
    /* Set up the test environment */
    t38_version = 1;
    without_pacing = FALSE;
    use_tep = FALSE;

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }

    in_handle = NULL;
    if (decode_test_file)
    {
        if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }

    srand48(0x1234567);
    if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }
    if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }

    t38_state = NULL;
    fax_state = NULL;
    if (test_sending)
    {
        if (t38_mode)
        {
            if ((t38_state = t38_terminal_init(NULL, FALSE, t38_tx_packet_handler, t31_state)) == NULL)
            {
                fprintf(stderr, "Cannot start the T.38 channel\n");
                exit(2);
            }
            t30 = t38_terminal_get_t30_state(t38_state);
        }
        else
        {
            fax_state = fax_init(NULL, FALSE);
            t30 = fax_get_t30_state(fax_state);
        }
        t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
        countdown = 0;
    }
    else
    {
        if (t38_mode)
        {
            if ((t38_state = t38_terminal_init(NULL, TRUE, t38_tx_packet_handler, t31_state)) == NULL)
            {
                fprintf(stderr, "Cannot start the T.38 channel\n");
                exit(2);
            }
            t30 = t38_terminal_get_t30_state(t38_state);
        }
        else
        {
            fax_state = fax_init(NULL, TRUE);
            t30 = fax_get_t30_state(fax_state);
        }
        t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
        countdown = 250;
    }

    t30_set_ecm_capability(t30, use_ecm);

    if (t38_mode)
    {
        t38_core = t38_terminal_get_t38_core_state(t38_state);
        t38_set_t38_version(t38_core, t38_version);
        t38_terminal_set_config(t38_state, without_pacing);
        t38_terminal_set_tep_mode(t38_state, use_tep);
    }

    t30_set_tx_ident(t30, "11111111");
    t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
    //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
    t30_set_phase_b_handler(t30, phase_b_handler, (void *) 'A');
    t30_set_phase_d_handler(t30, phase_d_handler, (void *) 'A');
    t30_set_phase_e_handler(t30, phase_e_handler, (void *) 'A');

    if (t38_mode)
        logging = t38_terminal_get_logging_state(t38_state);
    else
        logging = t30_get_logging_state(t30);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, (t38_mode)  ?  "T.38"  :  "FAX");

    if (t38_mode)
    {
        t38_core = t38_terminal_get_t38_core_state(t38_state);
        logging = t38_core_get_logging_state(t38_core);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        logging = t30_get_logging_state(t30);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");
    }
    else
    {
        logging = fax_get_logging_state(fax_state);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "FAX");
    }

    memset(silence, 0, sizeof(silence));
    memset(t30_amp, 0, sizeof(t30_amp));

    /* Now set up and run the T.31 modem */
    if ((t31_state = t31_init(NULL, at_tx_handler, &modem[0], t31_call_control, &modem[0], t31_tx_packet_handler, NULL)) == NULL)
    {
        fprintf(stderr, "    Cannot start the T.31 modem\n");
        exit(2);
    }
    at_state = t31_get_at_state(t31_state);

    logging = t31_get_logging_state(t31_state);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.31");

    logging = at_get_logging_state(at_state);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.31");

    if (t38_mode)
    {
        t38_core = t31_get_t38_core_state(t31_state);
        logging = t38_core_get_logging_state(t38_core);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.31");

        t31_set_mode(t31_state, TRUE);
        t38_set_t38_version(t38_core, t38_version);
    }

    at_reset_call_info(at_state);
    at_set_call_info(at_state, "DATE", "1231");
    at_set_call_info(at_state, "TIME", "1200");
    at_set_call_info(at_state, "NAME", "Name");
    at_set_call_info(at_state, "NMBR", "123456789");
    at_set_call_info(at_state, "ANID", "987654321");
    at_set_call_info(at_state, "USER", "User");
    at_set_call_info(at_state, "CDID", "234567890");
    at_set_call_info(at_state, "NDID", "345678901");

#if defined(ENABLE_GUI)
    if (use_gui)
        start_media_monitor();
#endif

    while (!done)
    {
        /* Deal with call setup, through the AT interface. */ 
        if (test_sending)
        {
        }
        else
        {
            if (answered == 0)
            {
                if (--countdown == 0)
                {
                    t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
                    countdown = 250;
                }
            }
            else if (answered == 1)
            {
printf("ZZZ\n");
                answered = 2;
                t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
            }
        }

        ret = modem_wait_sock(modem[0].master, 20, MODEM_POLL_READ);
        if ((ret & MODEM_POLL_READ))
        {
#if defined(WIN32)
			o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

			/* Initialize the rest of the OVERLAPPED structure to zero. */
			o.Internal = 0;
			o.InternalHigh = 0;
			o.Offset = 0;
			o.OffsetHigh = 0;
			assert(o.hEvent);
			if (!ReadFile(modem->master, buf, avail, &read_bytes, &o))
				GetOverlappedResult(modem->master, &o, &read_bytes, TRUE);
			CloseHandle (o.hEvent);
			if ((len = read_bytes))
#else
            if ((len = read(modem[0].master, buf, 1024)))
#endif
{
int i;

printf("YYY %d - ", len);
for (i = 0;  i < len;  i++)
    printf(" 0x%02x", buf[i] & 0xFF);
printf("\n");
                t31_at_rx(t31_state, buf, len);
}
        }

        if (answered == 2)
        {
            if (t38_mode)
            {
                while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
                {
#if defined(ENABLE_GUI)
                    if (use_gui)
                        media_monitor_rx(seq_no, tx_when, rx_when);
#endif
                    t38_core = t31_get_t38_core_state(t31_state);
                    t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
                }
                while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
                {
#if defined(ENABLE_GUI)
                    if (use_gui)
                        media_monitor_rx(seq_no, tx_when, rx_when);
#endif
                    t38_core = t38_terminal_get_t38_core_state(t38_state);
                    t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
                }
#if defined(ENABLE_GUI)
                if (use_gui)
                    media_monitor_update_display();
#endif
                /* Bump the G.1050 models along */
                when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;

                /* Bump things along on the t38_terminal side */
                span_log_bump_samples(t38_terminal_get_logging_state(t38_state), SAMPLES_PER_CHUNK);
                t38_core = t38_terminal_get_t38_core_state(t38_state);
                span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);

                t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK);
                t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK);
            }
            else
            {
                t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK);
                /* The receive side always expects a full block of samples, but the
                   transmit side may not be sending any when it doesn't need to. We
                   may need to pad with some silence. */
                if (t30_len < SAMPLES_PER_CHUNK)
                {
                    memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
                    t30_len = SAMPLES_PER_CHUNK;
                }
                if (log_audio)
                {
                    for (k = 0;  k < t30_len;  k++)
                        out_amp[2*k] = t30_amp[k];
                }
                if (t31_rx(t31_state, t30_amp, t30_len))
                    break;
                t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK);
                if (t31_len < SAMPLES_PER_CHUNK)
                {
                    memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
                    t31_len = SAMPLES_PER_CHUNK;
                }
                if (log_audio)
                {
                    for (k = 0;  k < t31_len;  k++)
                        out_amp[2*k + 1] = t31_amp[k];
                }
                if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
                    break;

                if (log_audio)
                {
                    outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
                    if (outframes != SAMPLES_PER_CHUNK)
                        break;
                }

                /* Bump things along on the FAX machine side */
                span_log_bump_samples(fax_get_logging_state(fax_state), SAMPLES_PER_CHUNK);
            }
            /* Bump things along on the FAX machine side */
            span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK);

            /* Bump things along on the T.31 modem side */
            t38_core = t31_get_t38_core_state(t31_state);
            span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
            span_log_bump_samples(t31_get_logging_state(t31_state), SAMPLES_PER_CHUNK);
            span_log_bump_samples(at_get_logging_state(t31_get_at_state(t31_state)), SAMPLES_PER_CHUNK);
        }
    }

    if (t38_mode)
        t38_terminal_release(t38_state);

    if (decode_test_file)
    {
        if (sf_close_telephony(in_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    if (log_audio)
    {
        if (sf_close_telephony(wave_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }

    if (!done)
    {
        printf("Tests failed\n");
        return 2;
    }

    return 0;
}
Beispiel #8
0
static int power_surge_detector_tests(void)
{
    SNDFILE *outhandle;
    power_surge_detector_state_t *sig;
    int i;
    int sample;
    int16_t amp[8000];
    int16_t amp_out[2*8000];
    awgn_state_t *awgnx;
    int32_t phase_rate;
    uint32_t phase_acc;
    int16_t phase_scale;
    float signal_power;
    int32_t signal_level;
    int signal_present;
    int prev_signal_present;
    int ok;
    int extremes[4];

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    sig = power_surge_detector_init(NULL, -50.0f, 5.0f);
    prev_signal_present = false;

    phase_rate = dds_phase_rate(450.0f);
    phase_acc = 0;

    phase_scale = dds_scaling_dbm0(-33.0f);
    awgnx = awgn_init_dbm0(NULL, 1234567, -45.0f);

    extremes[0] = 8001;
    extremes[1] = -1;
    extremes[2] = 8001;
    extremes[3] = -1;
    for (sample = 0;  sample < 800000;  sample += 8000)
    {
        ok = 0;
        for (i = 0;  i < 8000;  i++)
        {
            amp[i] = awgn(awgnx);
            if (i < 4000)
                amp[i] += dds_mod(&phase_acc, phase_rate, phase_scale, 0);

            signal_level = power_surge_detector(sig, amp[i]);
            signal_present = (signal_level != 0);
            if (prev_signal_present != signal_present)
            {
                signal_power = power_surge_detector_current_dbm0(sig);
                if (signal_present)
                {
                    if (ok == 0  &&  i >= 0  &&  i < 25)
                        ok = 1;
                    if (extremes[0] > i)
                        extremes[0] = i;
                    if (extremes[1] < i)
                        extremes[1] = i;
                    printf("On at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
                }
                else
                {
                    if (ok == 1  &&  i >= 4000 + 0  &&  i < 4000 + 35)
                        ok = 2;
                    if (extremes[2] > i)
                        extremes[2] = i;
                    if (extremes[3] < i)
                        extremes[3] = i;
                    printf("Off at %f (%fdBm0)\n", (sample + i)/8000.0, signal_power);
                }
                prev_signal_present = signal_present;
            }
            amp_out[2*i] = amp[i];
            amp_out[2*i + 1] = signal_present*5000;
        }
        sf_writef_short(outhandle, amp_out, 8000);
        if (ok != 2
            ||
            extremes[0] < 1
            ||
            extremes[1] > 30
            ||
            extremes[2] < 4001
            ||
            extremes[3] > 4030)
        {
            printf("    Surge not detected correctly (%d)\n", ok);
            exit(2);
        }
    }
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    printf("Min on %d, max on %d, min off %d, max off %d\n", extremes[0], extremes[1], extremes[2], extremes[3]);
    power_surge_detector_free(sig);
    awgn_free(awgnx);
    return 0;
}
Beispiel #9
0
static void test_both_ways_model(int line_model_no, int speech_test)
{
    both_ways_line_model_state_t *model;
    int16_t input1[BLOCK_LEN];
    int16_t input2[BLOCK_LEN];
    int16_t output1[BLOCK_LEN];
    int16_t output2[BLOCK_LEN];
    int16_t amp[2*BLOCK_LEN];
    SNDFILE *inhandle1;
    SNDFILE *inhandle2;
    SNDFILE *outhandle;
    int outframes;
    int samples;
    int i;
    int j;
    awgn_state_t noise1;
    awgn_state_t noise2;

    if ((model = both_ways_line_model_init(line_model_no,
                                           -50,
                                           -15.0f,
                                           -15.0f,
                                           line_model_no + 1,
                                           -35,
                                           -15.0f,
                                           -15.0f,
                                           channel_codec,
                                           rbs_pattern)) == NULL)
    {
        fprintf(stderr, "    Failed to create line model\n");
        exit(2);
    }

    awgn_init_dbm0(&noise1, 1234567, -10.0f);
    awgn_init_dbm0(&noise2, 1234567, -10.0f);

    if (speech_test)
    {
        if ((inhandle1 = sf_open_telephony_read(IN_FILE_NAME1, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", IN_FILE_NAME1);
            exit(2);
        }
        if ((inhandle2 = sf_open_telephony_read(IN_FILE_NAME2, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", IN_FILE_NAME2);
            exit(2);
        }
    }
    else
    {
        inhandle1 =
        inhandle2 = NULL;
    }
    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME2, 2)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME2);
        exit(2);
    }
    for (i = 0;  i < 10000;  i++)
    {
        if (speech_test)
        {
            samples = sf_readf_short(inhandle1, input1, BLOCK_LEN);
            if (samples == 0)
                break;
            samples = sf_readf_short(inhandle2, input2, samples);
            if (samples == 0)
                break;
        }
        else
        {
            for (j = 0;  j < BLOCK_LEN;  j++)
            {
                input1[j] = awgn(&noise1);
                input2[j] = awgn(&noise2);
            }
            samples = BLOCK_LEN;
        }
        for (j = 0;  j < samples;  j++)
        {
            both_ways_line_model(model,
                                 &output1[j],
                                 &input1[j],
                                 &output2[j],
                                 &input2[j],
                                 1);
            amp[2*j] = output1[j];
            amp[2*j + 1] = output2[j];
        }
        outframes = sf_writef_short(outhandle, amp, samples);
        if (outframes != samples)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }
    if (speech_test)
    {
        if (sf_close_telephony(inhandle1))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", IN_FILE_NAME1);
            exit(2);
        }
        if (sf_close_telephony(inhandle2))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", IN_FILE_NAME2);
            exit(2);
        }
    }
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME2);
        exit(2);
    }
    both_ways_line_model_free(model);
}
int main(int argc, char *argv[])
{
    tone_gen_descriptor_t tone_desc;
    tone_gen_state_t tone_state;
    int i;
    int16_t amp[16384];
    int len;
    SNDFILE *outhandle;
    int outframes;

    if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    /* Try a tone pair */
    tone_gen_descriptor_init(&tone_desc,
                             440,
                             -10,
                             620,
                             -15,
                             100,
                             200,
                             300,
                             400,
                             FALSE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }
    
    /* Try a different tone pair */
    tone_gen_descriptor_init(&tone_desc,
                             350,
                             -10,
                             440,
                             -15,
                             400,
                             300,
                             200,
                             100,
                             TRUE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }

    /* Try a different tone pair */
    tone_gen_descriptor_init(&tone_desc,
                             400,
                             -10,
                             450,
                             -10,
                             100,
                             200,
                             300,
                             400,
                             TRUE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }

    /* Try a single tone */
    tone_gen_descriptor_init(&tone_desc,
                             400,
                             -10,
                             0,
                             0,
                             100,
                             200,
                             300,
                             400,
                             TRUE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }

    /* Try a single non-repeating tone */
    tone_gen_descriptor_init(&tone_desc,
                             820,
                             -10,
                             0,
                             0,
                             2000,
                             0,
                             0,
                             0,
                             FALSE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }

    /* Try a single non-repeating tone at 0dBm0 */
    tone_gen_descriptor_init(&tone_desc,
                             820,
                             0,
                             0,
                             0,
                             2000,
                             0,
                             0,
                             0,
                             FALSE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }

    /* Try an AM modulated tone at a modest modulation level (25%) */
    tone_gen_descriptor_init(&tone_desc,
                             425,
                             -10,
                             -50,
                             25,
                             100,
                             200,
                             300,
                             400,
                             TRUE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }
    
    /* Try an AM modulated tone at maximum modulation level (100%) */
    tone_gen_descriptor_init(&tone_desc,
                             425,
                             -10,
                             -50,
                             100,
                             100,
                             200,
                             300,
                             400,
                             TRUE);
    tone_gen_init(&tone_state, &tone_desc);

    for (i = 0;  i < 1000;  i++)
    {
        len = tone_gen(&tone_state, amp, 160);
        printf("Generated %d samples\n", len);
        if (len <= 0)
            break;
        outframes = sf_writef_short(outhandle, amp, len);
    }
    
    if (sf_close(outhandle) != 0)
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
        exit (2);
    }

    return  0;
}
Beispiel #11
0
int main(int argc, char *argv[])
{
    g726_state_t *enc_state;
    g726_state_t *dec_state;
    int opt;
    int itutests;
    int bit_rate;
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int16_t amp[1024];
    int frames;
    int adpcm;
    int packing;

    bit_rate = 32000;
    itutests = true;
    packing = G726_PACKING_NONE;
    while ((opt = getopt(argc, argv, "b:LR")) != -1)
    {
        switch (opt)
        {
        case 'b':
            bit_rate = atoi(optarg);
            if (bit_rate != 16000  &&  bit_rate != 24000  &&  bit_rate != 32000  &&  bit_rate != 40000)
            {
                fprintf(stderr, "Invalid bit rate selected. Only 16000, 24000, 32000 and 40000 are valid.\n");
                exit(2);
            }
            itutests = false;
            break;
        case 'L':
            packing = G726_PACKING_LEFT;
            break;
        case 'R':
            packing = G726_PACKING_RIGHT;
            break;
        default:
            //usage();
            exit(2);
        }
    }

    if (itutests)
    {
        itu_compliance_tests();
    }
    else
    {
        if ((inhandle = sf_open_telephony_read(IN_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", IN_FILE_NAME);
            exit(2);
        }
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }

        printf("ADPCM packing is %d\n", packing);
        enc_state = g726_init(NULL, bit_rate, G726_ENCODING_LINEAR, packing);
        dec_state = g726_init(NULL, bit_rate, G726_ENCODING_LINEAR, packing);

        while ((frames = sf_readf_short(inhandle, amp, 159)))
        {
            adpcm = g726_encode(enc_state, adpcmdata, amp, frames);
            frames = g726_decode(dec_state, amp, adpcmdata, adpcm);
            sf_writef_short(outhandle, amp, frames);
        }
        if (sf_close_telephony(inhandle))
        {
            printf("    Cannot close audio file '%s'\n", IN_FILE_NAME);
            exit(2);
        }
        if (sf_close_telephony(outhandle))
        {
            printf("    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
        printf("'%s' transcoded to '%s' at %dbps.\n", IN_FILE_NAME, OUT_FILE_NAME, bit_rate);
        g726_free(enc_state);
        g726_free(dec_state);
    }
    return 0;
}
Beispiel #12
0
static int t30_tests(int log_audio, int test_sending)
{
    int k;
    int outframes;
    fax_state_t *fax_state;
    int16_t t30_amp[SAMPLES_PER_CHUNK];
    int16_t t31_amp[SAMPLES_PER_CHUNK];
    int16_t silence[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    int t30_len;
    int t31_len;
    SNDFILE *wave_handle;
    SNDFILE *in_handle;
    int fast_send;
    int fast_send_tcf;
    int fast_blocks;
    uint8_t fast_buf[1000];
    t30_state_t *t30;
    logging_state_t *logging;
    int i;

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }

    memset(silence, 0, sizeof(silence));
 
    in_handle = NULL;
    if (decode_test_file)
    {
        if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }

    if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, NULL, NULL)) == NULL)
    {
        fprintf(stderr, "    Cannot start the T.31 FAX modem\n");
        exit(2);
    }
    logging = t31_get_logging_state(t31_state);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.31");

    if (test_sending)
    {
        fax_state = fax_init(NULL, FALSE);
        t30 = fax_get_t30_state(fax_state);
        t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
        fax_test_seq = fax_send_test_seq;
        countdown = 0;
    }
    else
    {
        fax_state = fax_init(NULL, TRUE);
        t30 = fax_get_t30_state(fax_state);
        t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
        fax_test_seq = fax_receive_test_seq;
        countdown = 250;
    }
    
    t30_set_tx_ident(t30, "11111111");
    t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
    t30_set_phase_b_handler(t30, phase_b_handler, (void *) 'A');
    t30_set_phase_d_handler(t30, phase_d_handler, (void *) 'A');
    t30_set_phase_e_handler(t30, phase_e_handler, (void *) 'A');
    memset(t30_amp, 0, sizeof(t30_amp));
    
    logging = t30_get_logging_state(t30);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "FAX");

    logging = fax_get_logging_state(fax_state);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "FAX");

    fast_send = FALSE;
    fast_send_tcf = TRUE;
    fast_blocks = 0;
    kick = TRUE;
    while (!done)
    {
        if (kick)
        {
            kick = FALSE;
            if (fax_test_seq[test_seq_ptr].command > (const char *) 2)
            {
                if (fax_test_seq[test_seq_ptr].command[0])
                {
                    printf("%s\n", fax_test_seq[test_seq_ptr].command);
                    t31_at_rx(t31_state, fax_test_seq[test_seq_ptr].command, fax_test_seq[test_seq_ptr].len_command);
                }
            }
            else
            {
                if (fax_test_seq[test_seq_ptr].command == (const char *) 2)
                {
                    printf("Fast send TCF\n");
                    fast_send = TRUE;
                    fast_send_tcf = TRUE;
                    fast_blocks = 100;
                }
                else
                {
                    printf("Fast send image\n");
                    fast_send = TRUE;
                    fast_send_tcf = FALSE;
                    fast_blocks = 100;
                }
            }
        }
        if (fast_send)
        {
            /* Send fast modem data */
            if (fast_send_tcf)
            {
                memset(fast_buf, 0, 36);
            }
            else
            {
                if (fast_blocks == 1)
                {
                    /* Create the end of page condition */
                    for (i = 0;  i < 36;  i += 2)
                    {
                        fast_buf[i] = 0x00;
                        fast_buf[i + 1] = 0x80;
                    }
                }
                else
                {
                    /* Create a chunk of white page */
                    for (i = 0;  i < 36;  i += 4)
                    {
                        fast_buf[i] = 0x00;
                        fast_buf[i + 1] = 0x80;
                        fast_buf[i + 2] = 0xB2;
                        fast_buf[i + 3] = 0x01;
                    }
                }
            }
            if (fast_blocks == 1)
            {
                /* Insert EOLs */
                fast_buf[35] = ETX;
                fast_buf[34] = DLE;
                fast_buf[31] =
                fast_buf[28] =
                fast_buf[25] =
                fast_buf[22] =
                fast_buf[19] =
                fast_buf[16] = 1;
            }
            t31_at_rx(t31_state, (char *) fast_buf, 36);
            if (--fast_blocks == 0)
                fast_send = FALSE;
        }
        t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK);
        /* The receive side always expects a full block of samples, but the
           transmit side may not be sending any when it doesn't need to. We
           may need to pad with some silence. */
        if (t30_len < SAMPLES_PER_CHUNK)
        {
            memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
            t30_len = SAMPLES_PER_CHUNK;
        }
        if (log_audio)
        {
            for (k = 0;  k < t30_len;  k++)
                out_amp[2*k] = t30_amp[k];
        }
        if (t31_rx(t31_state, t30_amp, t30_len))
            break;
        if (countdown)
        {
            if (answered)
            {
                countdown = 0;
                t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
            }
            else if (--countdown == 0)
            {
                t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
                countdown = 250;
            }
        }

        t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK);
        if (t31_len < SAMPLES_PER_CHUNK)
        {
            memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
            t31_len = SAMPLES_PER_CHUNK;
        }
        if (log_audio)
        {
            for (k = 0;  k < t31_len;  k++)
                out_amp[2*k + 1] = t31_amp[k];
        }
        if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
            break;

        logging = fax_get_logging_state(fax_state);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        logging = t30_get_logging_state(t30);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        logging = t31_get_logging_state(t31_state);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);

        if (log_audio)
        {
            outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
            if (outframes != SAMPLES_PER_CHUNK)
                break;
        }
    }
    if (decode_test_file)
    {
        if (sf_close_telephony(in_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    if (log_audio)
    {
        if (sf_close_telephony(wave_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }
    return 0;
}
Beispiel #13
0
static int t30_tests(int t38_mode, int use_gui, int log_audio, int test_sending, int g1050_model_no, int g1050_speed_pattern_no)
{
    t38_terminal_state_t *t38_state;
    fax_state_t *fax_state;
    int fast_send;
    int fast_send_tcf;
    int fast_blocks;
    int msg_len;
    int t30_len;
    int t31_len;
    int t38_version;
    int without_pacing;
    int use_tep;
    int seq_no;
    int i;
    int k;
    int outframes;
    uint8_t fast_buf[1000];
    uint8_t msg[1024];
    double tx_when;
    double rx_when;
    t30_state_t *t30;
    t38_core_state_t *t38_core;
    logging_state_t *logging;
    int16_t t30_amp[SAMPLES_PER_CHUNK];
    int16_t t31_amp[SAMPLES_PER_CHUNK];
    int16_t silence[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    SNDFILE *wave_handle;
    SNDFILE *in_handle;

    /* Test the T.31 modem against the full FAX machine in spandsp */

    /* Set up the test environment */
    t38_version = 1;
    without_pacing = false;
    use_tep = false;

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }

    in_handle = NULL;
    if (decode_test_file)
    {
        if ((in_handle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }

    srand48(0x1234567);
    if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }
    if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }

    t38_state = NULL;
    fax_state = NULL;
    if (test_sending)
    {
        if (t38_mode)
        {
            if ((t38_state = t38_terminal_init(NULL, false, t38_tx_packet_handler, t31_state)) == NULL)
            {
                fprintf(stderr, "Cannot start the T.38 channel\n");
                exit(2);
            }
            t30 = t38_terminal_get_t30_state(t38_state);
        }
        else
        {
            fax_state = fax_init(NULL, false);
            t30 = fax_get_t30_state(fax_state);
        }
        t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
        fax_test_seq = fax_send_test_seq;
        countdown = 0;
    }
    else
    {
        if (t38_mode)
        {
            if ((t38_state = t38_terminal_init(NULL, true, t38_tx_packet_handler, t31_state)) == NULL)
            {
                fprintf(stderr, "Cannot start the T.38 channel\n");
                exit(2);
            }
            t30 = t38_terminal_get_t30_state(t38_state);
        }
        else
        {
            fax_state = fax_init(NULL, true);
            t30 = fax_get_t30_state(fax_state);
        }
        t30_set_tx_file(t30, INPUT_FILE_NAME, -1, -1);
        fax_test_seq = fax_receive_test_seq;
        countdown = 250;
    }

    if (t38_mode)
    {
        t38_core = t38_terminal_get_t38_core_state(t38_state);
        t38_set_t38_version(t38_core, t38_version);
        t38_terminal_set_config(t38_state, without_pacing);
        t38_terminal_set_tep_mode(t38_state, use_tep);
    }

    t30_set_tx_ident(t30, "11111111");
    t30_set_supported_modems(t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
    //t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
    t30_set_phase_b_handler(t30, phase_b_handler, (void *) 'A');
    t30_set_phase_d_handler(t30, phase_d_handler, (void *) 'A');
    t30_set_phase_e_handler(t30, phase_e_handler, (void *) 'A');

    if (t38_mode)
        logging = t38_terminal_get_logging_state(t38_state);
    else
        logging = t30_get_logging_state(t30);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, (t38_mode)  ?  "T.38"  :  "FAX");

    if (t38_mode)
    {
        t38_core = t38_terminal_get_t38_core_state(t38_state);
        span_log_set_level(&t38_core->logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(&t38_core->logging, "T.38");

        logging = t30_get_logging_state(t30);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");
    }
    else
    {
        logging = fax_get_logging_state(fax_state);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "FAX");
    }

    memset(silence, 0, sizeof(silence));
    memset(t30_amp, 0, sizeof(t30_amp));

    /* Now set up and run the T.31 modem */
    if ((t31_state = t31_init(NULL, at_tx_handler, NULL, modem_call_control, NULL, t31_tx_packet_handler, NULL)) == NULL)
    {
        fprintf(stderr, "    Cannot start the T.31 modem\n");
        exit(2);
    }
    logging = t31_get_logging_state(t31_state);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.31");

    logging = at_get_logging_state(t31_get_at_state(t31_state));
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.31");

    if (t38_mode)
    {
        t38_core = t31_get_t38_core_state(t31_state);
        logging = t38_core_get_logging_state(t38_core);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.31");

        t31_set_mode(t31_state, true);
        t38_set_t38_version(t38_core, t38_version);
    }

    fast_send = false;
    fast_send_tcf = true;
    fast_blocks = 0;
    kick = true;
#if defined(ENABLE_GUI)
    if (use_gui)
        start_media_monitor();
#endif
    while (!done)
    {
        if (countdown)
        {
            /* Deal with call setup, through the AT interface. */
            if (answered)
            {
                countdown = 0;
                t31_call_event(t31_state, AT_CALL_EVENT_ANSWERED);
            }
            else if (--countdown == 0)
            {
                t31_call_event(t31_state, AT_CALL_EVENT_ALERTING);
                countdown = 250;
            }
        }

        if (kick)
        {
            /* Work through the script */
            kick = false;
            if (fax_test_seq[test_seq_ptr].command > (const char *) 2)
            {
                if (fax_test_seq[test_seq_ptr].command[0])
                {
                    printf("%s\n", fax_test_seq[test_seq_ptr].command);
                    t31_at_rx(t31_state, fax_test_seq[test_seq_ptr].command, fax_test_seq[test_seq_ptr].len_command);
                }
            }
            else
            {
                if (fax_test_seq[test_seq_ptr].command == (const char *) 2)
                {
                    printf("Fast send TCF\n");
                    fast_send = true;
                    fast_send_tcf = true;
                    fast_blocks = 100;
                }
                else
                {
                    printf("Fast send image\n");
                    fast_send = true;
                    fast_send_tcf = false;
                    fast_blocks = 100;
                }
            }
        }
        if (fast_send)
        {
            /* Send fast modem data */
            if (fast_send_tcf)
            {
                /* If we are sending TCF, its simply zeros */
                memset(fast_buf, 0, 36);
                if (fast_blocks == 1)
                {
                    /* Tell the modem this is the end of the TCF data */
                    fast_buf[34] = DLE;
                    fast_buf[35] = ETX;
                }
            }
            else
            {
                /* If we are sending image data, we need to make it look like genuine image data,
                   with proper EOL and RTC markers. */
                if (fast_blocks > 1)
                {
                    /* Create a chunk of white page, 1728 pixels wide. */
                    for (i = 0;  i < 36;  i += 4)
                    {
                        fast_buf[i] = 0x00;
                        fast_buf[i + 1] = 0x80;
                        fast_buf[i + 2] = 0xB2;
                        fast_buf[i + 3] = 0x01;
                    }
                }
                else
                {
                    /* Create the end of page condition. */
                    for (i = 0;  i < 36;  i += 3)
                    {
                        fast_buf[i] = 0x00;
                        fast_buf[i + 1] = 0x08;
                        fast_buf[i + 2] = 0x80;
                    }
                    /* Tell the modem this is the end of the image data. */
                    fast_buf[34] = DLE;
                    fast_buf[35] = ETX;
                }
            }
            t31_at_rx(t31_state, (char *) fast_buf, 36);
            if (--fast_blocks == 0)
                fast_send = false;
        }

        if (t38_mode)
        {
            while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
            {
#if defined(ENABLE_GUI)
                if (use_gui)
                    media_monitor_rx(seq_no, tx_when, rx_when);
#endif
                t38_core = t31_get_t38_core_state(t31_state);
                t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
            }
            while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
            {
#if defined(ENABLE_GUI)
                if (use_gui)
                    media_monitor_rx(seq_no, tx_when, rx_when);
#endif
                t38_core = t38_terminal_get_t38_core_state(t38_state);
                t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
            }
#if defined(ENABLE_GUI)
            if (use_gui)
                media_monitor_update_display();
#endif
            /* Bump the G.1050 models along */
            when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;

            /* Bump things along on the t38_terminal side */
            span_log_bump_samples(t38_terminal_get_logging_state(t38_state), SAMPLES_PER_CHUNK);
            t38_core = t38_terminal_get_t38_core_state(t38_state);
            span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);

            t38_terminal_send_timeout(t38_state, SAMPLES_PER_CHUNK);
            t31_t38_send_timeout(t31_state, SAMPLES_PER_CHUNK);
        }
        else
        {
            t30_len = fax_tx(fax_state, t30_amp, SAMPLES_PER_CHUNK);
            /* The receive side always expects a full block of samples, but the
               transmit side may not be sending any when it doesn't need to. We
               may need to pad with some silence. */
            if (t30_len < SAMPLES_PER_CHUNK)
            {
                memset(t30_amp + t30_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len));
                t30_len = SAMPLES_PER_CHUNK;
            }
            if (log_audio)
            {
                for (k = 0;  k < t30_len;  k++)
                    out_amp[2*k] = t30_amp[k];
            }
            if (t31_rx(t31_state, t30_amp, t30_len))
                break;
            t31_len = t31_tx(t31_state, t31_amp, SAMPLES_PER_CHUNK);
            if (t31_len < SAMPLES_PER_CHUNK)
            {
                memset(t31_amp + t31_len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t31_len));
                t31_len = SAMPLES_PER_CHUNK;
            }
            if (log_audio)
            {
                for (k = 0;  k < t31_len;  k++)
                    out_amp[2*k + 1] = t31_amp[k];
            }
            if (fax_rx(fax_state, t31_amp, SAMPLES_PER_CHUNK))
                break;

            if (log_audio)
            {
                outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
                if (outframes != SAMPLES_PER_CHUNK)
                    break;
            }

            /* Bump things along on the FAX machine side */
            span_log_bump_samples(fax_get_logging_state(fax_state), SAMPLES_PER_CHUNK);
        }

        /* Bump things along on the FAX machine side */
        span_log_bump_samples(t30_get_logging_state(t30), SAMPLES_PER_CHUNK);

        /* Bump things along on the T.31 modem side */
        t38_core = t31_get_t38_core_state(t31_state);
        span_log_bump_samples(t38_core_get_logging_state(t38_core), SAMPLES_PER_CHUNK);
        span_log_bump_samples(t31_get_logging_state(t31_state), SAMPLES_PER_CHUNK);
        span_log_bump_samples(at_get_logging_state(t31_get_at_state(t31_state)), SAMPLES_PER_CHUNK);
    }

    if (t38_mode)
        t38_terminal_release(t38_state);

    if (decode_test_file)
    {
        if (sf_close_telephony(in_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    if (log_audio)
    {
        if (sf_close_telephony(wave_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }

    if (!done  ||  !sequence_terminated)
    {
        printf("Tests failed\n");
        return -1;
    }

    return 0;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
    int16_t silence[SAMPLES_PER_CHUNK];
    int16_t t30_amp[2][SAMPLES_PER_CHUNK];
    int16_t t38_amp[2][SAMPLES_PER_CHUNK];
    int16_t t38_amp_hist_a[8][SAMPLES_PER_CHUNK];
    int16_t t38_amp_hist_b[8][SAMPLES_PER_CHUNK];
    int16_t out_amp[SAMPLES_PER_CHUNK*4];
    int16_t *fax_rx_buf[2];
    int16_t *fax_tx_buf[2];
    int16_t *t38_gateway_rx_buf[2];
    int16_t *t38_gateway_tx_buf[2];
    int t30_len[2];
    int t38_len[2];
    int hist_ptr;
    int log_audio;
    int msg_len;
    uint8_t msg[1024];
    int outframes;
    SNDFILE *wave_handle;
    SNDFILE *input_wave_handle;
    int use_ecm;
    int use_tep;
    int feedback_audio;
    int use_transmit_on_idle;
    int t38_version;
    const char *input_tiff_file_name;
    const char *decode_file_name;
    int i;
    int j;
    int seq_no;
    int g1050_model_no;
    int g1050_speed_pattern_no;
    int t38_transport;
    double tx_when;
    double rx_when;
    int supported_modems;
    int remove_fill_bits;
    int opt;
    int start_page;
    int end_page;
    int drop_frame;
    int drop_frame_rate;
    float signal_scaling;
    int signal_level;
    int noise_level;
    int code_to_look_up;
    int scan_line_time;
    t38_stats_t t38_stats;
    t30_stats_t t30_stats;
    logging_state_t *logging;
    int expected_pages;
    char *page_header_info;
    char *page_header_tz;
    const char *tag;
    char buf[132 + 1];
#if defined(ENABLE_GUI)
    int use_gui;
#endif

#if defined(ENABLE_GUI)
    use_gui = FALSE;
#endif
    log_audio = FALSE;
    use_ecm = FALSE;
    t38_version = 1;
    input_tiff_file_name = INPUT_TIFF_FILE_NAME;
    t38_simulate_incrementing_repeats = FALSE;
    g1050_model_no = 0;
    g1050_speed_pattern_no = 1;
    remove_fill_bits = FALSE;
    use_tep = FALSE;
    feedback_audio = FALSE;
    use_transmit_on_idle = TRUE;
    supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17;
    page_header_info = NULL;
    page_header_tz = NULL;
    drop_frame = 0;
    drop_frame_rate = 0;
    start_page = -1;
    end_page = -1;
    signal_level = 0;
    noise_level = -99;
    scan_line_time = 0;
    decode_file_name = NULL;
    code_to_look_up = -1;
    t38_transport = T38_TRANSPORT_UDPTL;
    while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:tT:u:v:z:")) != -1)
    {
        switch (opt)
        {
        case 'c':
            code_to_look_up = atoi(optarg);
            break;
        case 'd':
            decode_file_name = optarg;
            break;
        case 'D':
            drop_frame_rate =
            drop_frame = atoi(optarg);
            break;
        case 'e':
            use_ecm = TRUE;
            break;
        case 'f':
            feedback_audio = TRUE;
            break;
        case 'F':
            remove_fill_bits = TRUE;
            break;
        case 'g':
#if defined(ENABLE_GUI)
            use_gui = TRUE;
#else
            fprintf(stderr, "Graphical monitoring not available\n");
            exit(2);
#endif
            break;
        case 'H':
            page_header_info = optarg;
            break;
        case 'i':
            input_tiff_file_name = optarg;
            break;
        case 'I':
            t38_simulate_incrementing_repeats = TRUE;
            break;
        case 'l':
            log_audio = TRUE;
            break;
        case 'm':
            supported_modems = atoi(optarg);
            break;
        case 'M':
            g1050_model_no = optarg[0] - 'A' + 1;
            break;
        case 'n':
            noise_level = atoi(optarg);
            break;
        case 'p':
            for (i = 0;  i < 2;  i++)
            {
                switch (optarg[i])
                {
                case 'A':
                    mode[i] = AUDIO_FAX;
                    break;
                case 'G':
                    mode[i] = T38_GATEWAY_FAX;
                    break;
                case 'T':
                    mode[i] = T38_TERMINAL_FAX;
                    break;
                default:
                    fprintf(stderr, "Unknown FAX path element %c\n", optarg[i]);
                    exit(2);
                }
            }
            if ((mode[0] == AUDIO_FAX  &&  mode[1] != AUDIO_FAX)
                ||
                (mode[0] != AUDIO_FAX  &&  mode[1] == AUDIO_FAX))
            {
                fprintf(stderr, "Invalid FAX path %s\n", optarg);
                exit(2);
            }
            break;
        case 's':
            g1050_speed_pattern_no = atoi(optarg);
            break;
#if 0
        case 's':
            signal_level = atoi(optarg);
            break;
#endif
        case 'S':
            scan_line_time = atoi(optarg);
            break;
        case 't':
            use_tep = TRUE;
            break;
        case 'T':
            start_page = 0;
            end_page = atoi(optarg);
            break;
        case 'u':
            if (strcasecmp(optarg, "udptl") == 0)
                t38_transport = T38_TRANSPORT_UDPTL;
            else if (strcasecmp(optarg, "rtp") == 0)
                t38_transport = T38_TRANSPORT_RTP;
            else if (strcasecmp(optarg, "tcp") == 0)
                t38_transport = T38_TRANSPORT_TCP;
            else if (strcasecmp(optarg, "tcp-tpkt") == 0)
                t38_transport = T38_TRANSPORT_TCP_TPKT;
            else
            {
                fprintf(stderr, "Unknown T.38 transport mode\n");
                exit(2);
            }
            break;
        case 'v':
            t38_version = atoi(optarg);
            break;
        case 'z':
            page_header_tz = optarg;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    if (code_to_look_up >= 0)
    {
        printf("Result code %d is %s\n", code_to_look_up, t30_completion_code_to_str(code_to_look_up));
        exit(0);
    }

    printf("Using T.38 version %d\n", t38_version);
    if (use_ecm)
        printf("Using ECM\n");

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 4)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            exit(2);
        }
    }
    memset(silence, 0, sizeof(silence));
 
    srand48(0x1234567);
    /* Set up the nodes */
    input_wave_handle = NULL;
    if (mode[0] == T38_TERMINAL_FAX)
    {
    }
    else
    {
        if (decode_file_name)
        {
            if ((input_wave_handle = sf_open_telephony_read(decode_file_name, 1)) == NULL)
            {
                fprintf(stderr, "    Cannot open audio file '%s'\n", decode_file_name);
                exit(2);
            }
        }
    }

    for (i = 0;  i < 2;  i++)
    {
        tag = (i == 0)  ?  "A"  :  "B";

        memset(&expected_rx_info[i], 0, sizeof(expected_rx_info[i]));
        if (mode[i] == T38_TERMINAL_FAX)
        {
            if ((t38_state[i] = t38_terminal_init(NULL, (i == 0), tx_packet_handler, (void *) (intptr_t) i)) == NULL)
            {
                fprintf(stderr, "Cannot start the T.38 terminal instance\n");
                exit(2);
            }
            t30_state[i] = t38_terminal_get_t30_state(t38_state[i]);
            t38_core_state[i] = t38_terminal_get_t38_core_state(t38_state[i]);

            logging = t38_terminal_get_logging_state(t38_state[i]);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);

            logging = t38_core_get_logging_state(t38_core_state[i]);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);

            logging = t30_get_logging_state(t30_state[i]);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);
        }
        else
        {
            if ((fax_state[i] = fax_init(NULL, (i == 0))) == NULL)
            {
                fprintf(stderr, "Cannot start FAX instance\n");
                exit(2);
            }
            t30_state[i] = fax_get_t30_state(fax_state[i]);

            logging = fax_get_logging_state(fax_state[i]);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);

            logging = fax_modems_get_logging_state(&fax_state[i]->modems);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);

            logging = t30_get_logging_state(t30_state[i]);
            span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
            span_log_set_tag(logging, tag);

            if (mode[i] == T38_GATEWAY_FAX)
            {
                if ((t38_gateway_state[i] = t38_gateway_init(NULL, tx_packet_handler, (void *) (intptr_t) i)) == NULL)
                {
                    fprintf(stderr, "Cannot start the T.38 gateway instancel\n");
                    exit(2);
                }
                t38_core_state[i] = t38_gateway_get_t38_core_state(t38_gateway_state[i]);

                logging = t38_gateway_get_logging_state(t38_gateway_state[i]);
                span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
                span_log_set_tag(logging, tag);

                logging = fax_modems_get_logging_state(&t38_gateway_state[i]->audio.modems);
                span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
                span_log_set_tag(logging, tag);

                logging = t38_core_get_logging_state(t38_core_state[i]);
                span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
                span_log_set_tag(logging, tag);

                fax_rx_buf[i] = t38_amp[i];
                fax_tx_buf[i] = t30_amp[i];
                t38_gateway_rx_buf[i] = t30_amp[i];
                t38_gateway_tx_buf[i] = t38_amp[i];
            }
            else
            {
                fax_rx_buf[i] = t30_amp[i];
                fax_tx_buf[i] = t30_amp[i ^ 1];
                t38_gateway_rx_buf[i] = NULL;
                t38_gateway_tx_buf[i] = NULL;
            }
            awgn_state[i] = NULL;
            signal_scaling = 1.0f;
            if (noise_level > -99)
            {
                awgn_state[i] = awgn_init_dbm0(NULL, 1234567, noise_level);
                signal_scaling = powf(10.0f, signal_level/20.0f);
                printf("Signal scaling %f\n", signal_scaling);
            }
        }
        set_t30_callbacks(t30_state[i], i);
    }
    /* Set up the channels */
    for (i = 0;  i < 2;  i++)
    {
        if ((g1050_path[i] = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
        {
            fprintf(stderr, "Failed to start IP network path model\n");
            exit(2);
        }
        memset(audio_buffer[2*i], 0, SAMPLES_PER_CHUNK*sizeof(int16_t));
        memset(audio_buffer[2*i + 1], 0, SAMPLES_PER_CHUNK*sizeof(int16_t));
        memset(t30_amp[i], 0, sizeof(t30_amp[i]));
        memset(t38_amp[i], 0, sizeof(t38_amp[i]));
    }
    memset(t38_amp_hist_a, 0, sizeof(t38_amp_hist_a));
    memset(t38_amp_hist_b, 0, sizeof(t38_amp_hist_b));

    for (i = 0;  i < 2;  i++)
    {
        j = i + 1;
        sprintf(buf, "%d%d%d%d%d%d%d%d", j, j, j, j, j, j, j, j);
        t30_set_tx_ident(t30_state[i], buf);
        strcpy(expected_rx_info[i ^ 1].ident, buf);
        sprintf(buf, "Sub-address %d", j);
        t30_set_tx_sub_address(t30_state[i], buf);
        //strcpy(expected_rx_info[i ^ 1].sub_address, buf);
        sprintf(buf, "Sender ID %d", j);
        t30_set_tx_sender_ident(t30_state[i], buf);
        //strcpy(expected_rx_info[i ^ 1].sender_ident, buf);
        sprintf(buf, "Password %d", j);
        t30_set_tx_password(t30_state[i], buf);
        //strcpy(expected_rx_info[i ^ 1].password, buf);
        sprintf(buf, "Polled sub-add %d", j);
        t30_set_tx_polled_sub_address(t30_state[i], buf);
        //strcpy(expected_rx_info[i ^ 1].polled_sub_address, buf);
        sprintf(buf, "Select poll add %d", j);
        t30_set_tx_selective_polling_address(t30_state[i], buf);
        //strcpy(expected_rx_info[i ^ 1].selective_polling_address, buf);
        t30_set_tx_page_header_info(t30_state[i], page_header_info);
        if (page_header_tz)
            t30_set_tx_page_header_tz(t30_state[i], page_header_tz);

        if ((i & 1) == 1)
        {
            t30_set_tx_nsf(t30_state[i], (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
            expected_rx_info[i ^ 1].nsf = (uint8_t *) "\x50\x00\x00\x00Spandsp\x00";
            expected_rx_info[i ^ 1].nsf_len = 12;
        }

        t30_set_supported_modems(t30_state[i], supported_modems);
        t30_set_supported_t30_features(t30_state[i],
                                       T30_SUPPORT_IDENTIFICATION
                                     | T30_SUPPORT_SELECTIVE_POLLING
                                     | T30_SUPPORT_SUB_ADDRESSING);
        t30_set_supported_image_sizes(t30_state[i],
                                      T30_SUPPORT_US_LETTER_LENGTH
                                    | T30_SUPPORT_US_LEGAL_LENGTH
                                    | T30_SUPPORT_UNLIMITED_LENGTH
                                    | T30_SUPPORT_215MM_WIDTH
                                    | T30_SUPPORT_255MM_WIDTH
                                    | T30_SUPPORT_303MM_WIDTH);
        t30_set_supported_resolutions(t30_state[i],
                                      T30_SUPPORT_STANDARD_RESOLUTION
                                    | T30_SUPPORT_FINE_RESOLUTION
                                    | T30_SUPPORT_SUPERFINE_RESOLUTION
                                    | T30_SUPPORT_R8_RESOLUTION
                                    | T30_SUPPORT_R16_RESOLUTION
                                    | T30_SUPPORT_300_300_RESOLUTION
                                    | T30_SUPPORT_400_400_RESOLUTION
                                    | T30_SUPPORT_600_600_RESOLUTION
                                    | T30_SUPPORT_1200_1200_RESOLUTION
                                    | T30_SUPPORT_300_600_RESOLUTION
                                    | T30_SUPPORT_400_800_RESOLUTION
                                    | T30_SUPPORT_600_1200_RESOLUTION);
        t30_set_ecm_capability(t30_state[i], use_ecm);
        if (use_ecm)
        {
            t30_set_supported_compressions(t30_state[i],
                                           T30_SUPPORT_T4_1D_COMPRESSION
                                         | T30_SUPPORT_T4_2D_COMPRESSION
                                         | T30_SUPPORT_T6_COMPRESSION
                                         | T30_SUPPORT_T81_COMPRESSION
                                         | T30_SUPPORT_T85_COMPRESSION
                                         | T30_SUPPORT_T85_L0_COMPRESSION);
        }
        else
        {
            t30_set_supported_compressions(t30_state[i],
                                           T30_SUPPORT_T4_1D_COMPRESSION
                                         | T30_SUPPORT_T4_2D_COMPRESSION);
        }
        t30_set_minimum_scan_line_time(t30_state[i], scan_line_time);

        if (mode[i] == T38_GATEWAY_FAX)
        {
            t38_gateway_set_transmit_on_idle(t38_gateway_state[i], use_transmit_on_idle);
            t38_gateway_set_supported_modems(t38_gateway_state[i], supported_modems);
            //t38_gateway_set_nsx_suppression(t38_state[i], NULL, 0, NULL, 0);
            t38_gateway_set_fill_bit_removal(t38_gateway_state[i], remove_fill_bits);
            t38_gateway_set_real_time_frame_handler(t38_gateway_state[i], real_time_gateway_frame_handler, (void *) (intptr_t) i);
            t38_gateway_set_ecm_capability(t38_gateway_state[i], use_ecm);
        }
        if (mode[i] != AUDIO_FAX)
        {
            t38_set_t38_version(t38_core_state[i], t38_version);
        }

        if (mode[i] == T38_TERMINAL_FAX)
        {
            //t30_set_iaf_mode(t30_state[i], T30_IAF_MODE_NO_FILL_BITS);
            switch (t38_transport)
            {
            case T38_TRANSPORT_UDPTL:
            case T38_TRANSPORT_RTP:
                t38_terminal_set_fill_bit_removal(t38_state[i], remove_fill_bits);
                t38_terminal_set_tep_mode(t38_state[i], use_tep);
                break;
            case T38_TRANSPORT_TCP:
            case T38_TRANSPORT_TCP_TPKT:
                t38_terminal_set_fill_bit_removal(t38_state[i], TRUE);
                t38_terminal_set_config(t38_state[i], T38_TERMINAL_OPTION_NO_PACING | T38_TERMINAL_OPTION_NO_INDICATORS);
                t38_terminal_set_tep_mode(t38_state[i], FALSE);
                break;
            }
        }
        else
        {
            fax_set_transmit_on_idle(fax_state[i], use_transmit_on_idle);
            fax_set_tep_mode(fax_state[i], use_tep);
        }
    }

    t30_set_tx_file(t30_state[0], input_tiff_file_name, start_page, end_page);
    t30_set_rx_file(t30_state[1], OUTPUT_TIFF_FILE_NAME, -1);

#if defined(ENABLE_GUI)
    if (use_gui)
        start_media_monitor();
#endif
    hist_ptr = 0;
    for (;;)
    {
        memset(out_amp, 0, sizeof(out_amp));

        for (i = 0;  i < 2;  i++)
        {
            /* Update T.30 timing */
            logging = t30_get_logging_state(t30_state[i]);
            span_log_bump_samples(logging, SAMPLES_PER_CHUNK);

            if (mode[i] == T38_TERMINAL_FAX)
            {
                /* Update T.38 termination timing */
                logging = t38_terminal_get_logging_state(t38_state[i]);
                span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
                logging = t38_core_get_logging_state(t38_core_state[i]);
                span_log_bump_samples(logging, SAMPLES_PER_CHUNK);

                completed[i] = t38_terminal_send_timeout(t38_state[i], SAMPLES_PER_CHUNK);
            }
            else
            {
                /* Update audio FAX timing */
                logging = fax_get_logging_state(fax_state[i]);
                span_log_bump_samples(logging, SAMPLES_PER_CHUNK);

                fax_rx(fax_state[i], fax_rx_buf[i], SAMPLES_PER_CHUNK);
                if (!t30_call_active(t30_state[i]))
                {
                    completed[i] = TRUE;
                    continue;
                }

                if (i == 0  &&  input_wave_handle)
                {
                    t30_len[i] = sf_readf_short(input_wave_handle, fax_tx_buf[i], SAMPLES_PER_CHUNK);
                    if (t30_len[i] == 0)
                        break;
                }
                else
                {
                    t30_len[i] = fax_tx(fax_state[i], fax_tx_buf[i], SAMPLES_PER_CHUNK);
                    if (!use_transmit_on_idle)
                    {
                        /* The receive side always expects a full block of samples, but the
                           transmit side may not be sending any when it doesn't need to. We
                           may need to pad with some silence. */
                        if (t30_len[i] < SAMPLES_PER_CHUNK)
                        {
                            memset(t30_amp[i] + t30_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len[i]));
                            t30_len[i] = SAMPLES_PER_CHUNK;
                        }
                    }
                    if (awgn_state[i])
                    {
                        for (j = 0;  j < t30_len[i];  j++)
                            fax_tx_buf[i][j] = ((int16_t) (fax_tx_buf[i][j]*signal_scaling)) + awgn(awgn_state[i]);
                    }
                }
                if (log_audio)
                {
                    for (j = 0;  j < t30_len[i];  j++)
                        out_amp[4*j + 2*i] = t30_amp[i][j];
                }
                if (feedback_audio)
                {
                    for (j = 0;  j < t30_len[i];  j++)
                        t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1;
                    memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK);
                }

                if (mode[i] == T38_GATEWAY_FAX)
                {
                    /* Update T.38 gateway timing */
                    logging = t38_gateway_get_logging_state(t38_gateway_state[i]);
                    span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
                    logging = t38_core_get_logging_state(t38_core_state[i]);
                    span_log_bump_samples(logging, SAMPLES_PER_CHUNK);

                    if (drop_frame_rate  &&  --drop_frame == 0)
                    {
                        drop_frame = drop_frame_rate;
                        if (t38_gateway_rx_fillin(t38_gateway_state[i], SAMPLES_PER_CHUNK))
                            break;
                    }
                    else
                    {
                        if (t38_gateway_rx(t38_gateway_state[i], t38_gateway_rx_buf[i], SAMPLES_PER_CHUNK))
                            break;
                    }

                    t38_len[i] = t38_gateway_tx(t38_gateway_state[i], t38_gateway_tx_buf[i], SAMPLES_PER_CHUNK);
                    if (!use_transmit_on_idle)
                    {
                        if (t38_len[i] < SAMPLES_PER_CHUNK)
                        {
                            memset(t38_amp[i] + t38_len[i], 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len[i]));
                            t38_len[i] = SAMPLES_PER_CHUNK;
                        }
                    }
                    if (feedback_audio)
                    {
                        for (j = 0;  j < t30_len[i];  j++)
                            t30_amp[i][j] += t38_amp_hist_a[hist_ptr][j] >> 1;
                        memcpy(t38_amp_hist_a[hist_ptr], t38_amp[i], sizeof(int16_t)*SAMPLES_PER_CHUNK);
                    }

                    if (log_audio)
                    {
                        for (j = 0;  j < t38_len[i];  j++)
                            out_amp[4*j + 2*i + 1] = t38_amp[i][j];
                    }
                }
            }
            if (mode[i] != AUDIO_FAX)
            {
                while ((msg_len = g1050_get(g1050_path[i], msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
                {
#if defined(ENABLE_GUI)
                    if (use_gui)
                        media_monitor_rx(seq_no, tx_when, rx_when);
#endif
                   t38_core_rx_ifp_packet(t38_core_state[i ^ 1], msg, msg_len, seq_no);
                }
            }
        }
        if (log_audio)
        {
            outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
            if (outframes != SAMPLES_PER_CHUNK)
                break;
        }

        when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;

        if (completed[0]  &&  completed[1])
            break;
#if defined(ENABLE_GUI)
        if (use_gui)
            media_monitor_update_display();
#endif
        if (++hist_ptr > 3)
            hist_ptr = 0;
    }
Beispiel #15
0
int main(int argc, char *argv[])
{
    int16_t amp[SAMPLES_PER_CHUNK];
    int samples;
    int caller_available_modulations;
    int answerer_available_modulations;
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int opt;
    int log_audio;
    char *decode_test_file;
    v8_state_t *v8_caller;
    v8_state_t *v8_answerer;
    v8_parms_t v8_call_parms;
    v8_parms_t v8_answer_parms;
    logging_state_t *logging;

    decode_test_file = NULL;
    log_audio = false;
    while ((opt = getopt(argc, argv, "d:l")) != -1)
    {
        switch (opt)
        {
        case 'd':
            decode_test_file = optarg;
            break;
        case 'l':
            log_audio = true;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    if (decode_test_file)
    {
        caller_available_modulations = V8_MOD_V17
                                     | V8_MOD_V21
                                     | V8_MOD_V22
                                     | V8_MOD_V23HDX
                                     | V8_MOD_V23
                                     | V8_MOD_V26BIS
                                     | V8_MOD_V26TER
                                     | V8_MOD_V27TER
                                     | V8_MOD_V29
                                     | V8_MOD_V32
                                     | V8_MOD_V34HDX
                                     | V8_MOD_V34
                                     | V8_MOD_V90
                                     | V8_MOD_V92;
        answerer_available_modulations = V8_MOD_V17
                                       | V8_MOD_V21
                                       | V8_MOD_V22
                                       | V8_MOD_V23HDX
                                       | V8_MOD_V23
                                       | V8_MOD_V26BIS
                                       | V8_MOD_V26TER
                                       | V8_MOD_V27TER
                                       | V8_MOD_V29
                                       | V8_MOD_V32
                                       | V8_MOD_V34HDX
                                       | V8_MOD_V34
                                       | V8_MOD_V90
                                       | V8_MOD_V92;

        printf("Decode file '%s'\n", decode_test_file);
        v8_call_parms.modem_connect_tone = MODEM_CONNECT_TONES_NONE;
        v8_call_parms.send_ci = true;
        v8_call_parms.v92 = -1;
        v8_call_parms.call_function = V8_CALL_V_SERIES;
        v8_call_parms.modulations = caller_available_modulations;
        v8_call_parms.protocol = V8_PROTOCOL_LAPM_V42;
        v8_call_parms.pcm_modem_availability = 0;
        v8_call_parms.pstn_access = 0;
        v8_call_parms.nsf = -1;
        v8_call_parms.t66 = -1;
        v8_caller = v8_init(NULL,
                            true,
                            &v8_call_parms,
                            handler,
                            (void *) "caller");
        logging = v8_get_logging_state(v8_caller);
        span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
        span_log_set_tag(logging, "caller");

        v8_answer_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
        v8_answer_parms.send_ci = true;
        v8_answer_parms.v92 = -1;
        v8_answer_parms.call_function = V8_CALL_V_SERIES;
        v8_answer_parms.modulations = answerer_available_modulations;
        v8_answer_parms.protocol = V8_PROTOCOL_LAPM_V42;
        v8_answer_parms.pcm_modem_availability = 0;
        v8_answer_parms.pstn_access = 0;
        v8_answer_parms.nsf = -1;
        v8_answer_parms.t66 = -1;
        v8_answerer = v8_init(NULL,
                              false,
                              &v8_answer_parms,
                              handler,
                              (void *) "answerer");
        logging = v8_get_logging_state(v8_answerer);
        span_log_set_level(logging, SPAN_LOG_FLOW | SPAN_LOG_SHOW_TAG);
        span_log_set_tag(logging, "answerer");

        if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open speech file '%s'\n", decode_test_file);
            exit (2);
        }
        /*endif*/

        while ((samples = sf_readf_short(inhandle, amp, SAMPLES_PER_CHUNK)))
        {
            v8_rx(v8_caller, amp, samples);
            v8_rx(v8_answerer, amp, samples);
            v8_tx(v8_caller, amp, samples);
            v8_tx(v8_answerer, amp, samples);
        }
        /*endwhile*/

        v8_free(v8_caller);
        v8_free(v8_answerer);
        if (sf_close_telephony(inhandle))
        {
            fprintf(stderr, "    Cannot close speech file '%s'\n", decode_test_file);
            exit(2);
        }
        /*endif*/
    }
    else
    {
        outhandle = NULL;
        if (log_audio)
        {
            if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL)
            {
                fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
                exit(2);
            }
            /*endif*/
        }
        /*endif*/

        printf("Test 1: V.8 terminal calls V.8 terminal\n");
        v8_calls_v8_tests(outhandle);

        printf("Test 2: non-V.8 terminal calls V.8 terminal\n");
        non_v8_calls_v8_tests(outhandle);

        printf("Test 3: V.8 terminal calls non-V.8 terminal\n");
        v8_calls_non_v8_tests(outhandle);

        if (outhandle)
        {
            if (sf_close_telephony(outhandle))
            {
                fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
                exit(2);
            }
            /*endif*/
        }
        /*endif*/

        printf("Tests passed.\n");
    }
    return 0;
}
int main(int argc, char *argv[])
{
    int16_t t38_amp_b[SAMPLES_PER_CHUNK];
    int16_t t30_amp_b[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    int t38_len_b;
    int t30_len_b;
    int msg_len;
    uint8_t msg[1024];
    int log_audio;
    int outframes;
    SNDFILE *wave_handle;
    int t38_version;
    int use_ecm;
    int use_tep;
    int feedback_audio;
    int use_transmit_on_idle;
    const char *input_file_name;
    int i;
    int seq_no;
    int g1050_model_no;
    int g1050_speed_pattern_no;
    double tx_when;
    double rx_when;
    int use_gui;
    int supported_modems;
    int opt;
    t30_state_t *t30;
    t38_core_state_t *t38_core;
    logging_state_t *logging;

    log_audio = false;
    t38_version = 1;
    use_ecm = false;
    input_file_name = INPUT_FILE_NAME;
    simulate_incrementing_repeats = false;
    g1050_model_no = 0;
    g1050_speed_pattern_no = 1;
    use_gui = false;
    use_tep = false;
    feedback_audio = false;
    use_transmit_on_idle = true;
    supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17;
    while ((opt = getopt(argc, argv, "efgi:Ilm:M:s:tv:")) != -1)
    {
        switch (opt)
        {
        case 'e':
            use_ecm = true;
            break;
        case 'f':
            feedback_audio = true;
            break;
        case 'g':
#if defined(ENABLE_GUI)
            use_gui = true;
#else
            fprintf(stderr, "Graphical monitoring not available\n");
            exit(2);
#endif
            break;
        case 'i':
            input_file_name = optarg;
            break;
        case 'I':
            simulate_incrementing_repeats = true;
            break;
        case 'l':
            log_audio = true;
            break;
        case 'm':
            supported_modems = atoi(optarg);
            break;
        case 'M':
            g1050_model_no = optarg[0] - 'A' + 1;
            break;
        case 's':
            g1050_speed_pattern_no = atoi(optarg);
            break;
        case 't':
            use_tep = true;
            break;
        case 'v':
            t38_version = atoi(optarg);
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    printf("Using T.38 version %d\n", t38_version);
    if (use_ecm)
        printf("Using ECM\n");

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
            exit(2);
        }
    }

    srand48(0x1234567);
    if ((path_a_to_b = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }
    if ((path_b_to_a = g1050_init(g1050_model_no, g1050_speed_pattern_no, 100, 33)) == NULL)
    {
        fprintf(stderr, "Failed to start IP network path model\n");
        exit(2);
    }

    if ((t38_state_a = t38_terminal_init(NULL, true, tx_packet_handler_a, &t38_state_b)) == NULL)
    {
        fprintf(stderr, "Cannot start the T.38 channel\n");
        exit(2);
    }
    t30 = t38_terminal_get_t30_state(t38_state_a);
    t38_core = t38_terminal_get_t38_core_state(t38_state_a);
    t38_set_t38_version(t38_core, t38_version);

    logging = t38_terminal_get_logging_state(t38_state_a);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.38-A");

    logging = t38_core_get_logging_state(t38_core);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.38-A");

    logging = t30_get_logging_state(t30);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.38-A");

    t30_set_supported_modems(t30, supported_modems);
    t30_set_tx_ident(t30, "11111111");
    t30_set_tx_file(t30, input_file_name, -1, -1);
    t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A');
    t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A');
    t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A');
    t30_set_ecm_capability(t30, use_ecm);
    if (use_ecm)
        t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);

    if ((t38_state_b = t38_gateway_init(NULL, tx_packet_handler_b, &t38_state_a)) == NULL)
    {
        fprintf(stderr, "Cannot start the T.38 channel\n");
        exit(2);
    }
    t38_core = t38_gateway_get_t38_core_state(t38_state_b);
    t38_gateway_set_transmit_on_idle(t38_state_b, use_transmit_on_idle);
    t38_set_t38_version(t38_core, t38_version);
    t38_gateway_set_ecm_capability(t38_state_b, use_ecm);

    logging = t38_gateway_get_logging_state(t38_state_b);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.38-B");

    logging = t38_core_get_logging_state(t38_core);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "T.38-B");

    memset(t38_amp_b, 0, sizeof(t38_amp_b));

    if ((fax_state_b = fax_init(NULL, false)) == NULL)
    {
        fprintf(stderr, "Cannot start FAX\n");
        exit(2);
    }
    t30 = fax_get_t30_state(fax_state_b);
    fax_set_transmit_on_idle(fax_state_b, use_transmit_on_idle);
    fax_set_tep_mode(fax_state_b, use_tep);
    t30_set_supported_modems(t30, supported_modems);
    t30_set_tx_ident(t30, "22222222");
    t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
    t30_set_rx_file(t30, OUTPUT_FILE_NAME, -1);
    t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B');
    t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B');
    t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B');
    t30_set_ecm_capability(t30, use_ecm);
    if (use_ecm)
        t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);

    logging = fax_get_logging_state(fax_state_b);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "FAX-B ");

    logging = t30_get_logging_state(t30);
    span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
    span_log_set_tag(logging, "FAX-B ");

    memset(t30_amp_b, 0, sizeof(t30_amp_b));

#if defined(ENABLE_GUI)
    if (use_gui)
        start_media_monitor();
#endif
    for (;;)
    {
        logging = t38_terminal_get_logging_state(t38_state_a);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        t38_core = t38_terminal_get_t38_core_state(t38_state_a);
        logging = t38_core_get_logging_state(t38_core);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        t30 = t38_terminal_get_t30_state(t38_state_a);
        logging = t30_get_logging_state(t30);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        logging = t38_gateway_get_logging_state(t38_state_b);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        t38_core = t38_gateway_get_t38_core_state(t38_state_b);
        logging = t38_core_get_logging_state(t38_core);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        logging = fax_get_logging_state(fax_state_b);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        t30 = fax_get_t30_state(fax_state_b);
        logging = t30_get_logging_state(t30);
        span_log_bump_samples(logging, SAMPLES_PER_CHUNK);
        memset(out_amp, 0, sizeof(out_amp));

        t38_terminal_send_timeout(t38_state_a, SAMPLES_PER_CHUNK);

        t30_len_b = fax_tx(fax_state_b, t30_amp_b, SAMPLES_PER_CHUNK);
        if (!use_transmit_on_idle)
        {
            /* The receive side always expects a full block of samples, but the
               transmit side may not be sending any when it doesn't need to. We
               may need to pad with some silence. */
            if (t30_len_b < SAMPLES_PER_CHUNK)
            {
                memset(t30_amp_b + t30_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t30_len_b));
                t30_len_b = SAMPLES_PER_CHUNK;
            }
        }
        if (feedback_audio)
        {
            for (i = 0;  i < t30_len_b;  i++)
                t30_amp_b[i] += t38_amp_b[i] >> 1;
        }
        if (log_audio)
        {
            for (i = 0;  i < t30_len_b;  i++)
                out_amp[2*i + 1] = t30_amp_b[i];
        }
        if (t38_gateway_rx(t38_state_b, t30_amp_b, t30_len_b))
            break;
    
        t38_len_b = t38_gateway_tx(t38_state_b, t38_amp_b, SAMPLES_PER_CHUNK);
        if (!use_transmit_on_idle)
        {
            if (t38_len_b < SAMPLES_PER_CHUNK)
            {
                memset(t38_amp_b + t38_len_b, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - t38_len_b));
                t38_len_b = SAMPLES_PER_CHUNK;
            }
        }
        if (log_audio)
        {
            for (i = 0;  i < t38_len_b;  i++)
                out_amp[2*i] = t38_amp_b[i];
        }
        if (fax_rx(fax_state_b, t38_amp_b, SAMPLES_PER_CHUNK))
            break;

        when += (float) SAMPLES_PER_CHUNK/(float) SAMPLE_RATE;

        while ((msg_len = g1050_get(path_a_to_b, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
        {
#if defined(ENABLE_GUI)
            if (use_gui)
                media_monitor_rx(seq_no, tx_when, rx_when);
#endif
            t38_core = t38_gateway_get_t38_core_state(t38_state_b);
            t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
        }
        while ((msg_len = g1050_get(path_b_to_a, msg, 1024, when, &seq_no, &tx_when, &rx_when)) >= 0)
        {
#if defined(ENABLE_GUI)
            if (use_gui)
                media_monitor_rx(seq_no, tx_when, rx_when);
#endif
            t38_core = t38_terminal_get_t38_core_state(t38_state_a);
            t38_core_rx_ifp_packet(t38_core, msg, msg_len, seq_no);
        }
        if (log_audio)
        {
            outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
            if (outframes != SAMPLES_PER_CHUNK)
                break;
        }

        if (done[0]  &&  done[1])
            break;
#if defined(ENABLE_GUI)
        if (use_gui)
            media_monitor_update_display();
#endif
    }
    t38_terminal_release(t38_state_a);
    fax_release(fax_state_b);
    if (log_audio)
    {
        if (sf_close(wave_handle) != 0)
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
            exit(2);
        }
    }
    if (!succeeded[0]  ||  !succeeded[1])
    {
        printf("Tests failed\n");
        exit(2);
    }
    printf("Tests passed\n");
    return 0;
}
Beispiel #17
0
int main(int argc, char *argv[])
{
    t30_state_t *t30;
    logging_state_t *logging;
    const char *input_file_name;
    int t38_version;
    int caller;
    int use_ecm;
    int use_tep;
    int options;
    int supported_modems;
    int fill_removal;
    int opt;
    int t38_terminal_operation;
    uint32_t src_addr;
    uint16_t src_port;
    uint32_t dest_addr;
    uint16_t dest_port;

    caller = false;
    use_ecm = false;
    t38_version = 0;
    options = 0;
    input_file_name = INPUT_FILE_NAME;
    fill_removal = false;
    use_tep = false;
    use_transmit_on_idle = true;
    supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17;
    t38_terminal_operation = true;
    log_audio = false;
    src_addr = 0;
    src_port = 0;
    dest_addr = 0;
    dest_port = 0;
    while ((opt = getopt(argc, argv, "cD:d:eFGi:lm:oS:s:tv:")) != -1)
    {
        switch (opt)
        {
        case 'c':
            caller = true;
            break;
        case 'D':
            dest_addr = parse_inet_addr(optarg);
            break;
        case 'd':
            dest_port = atoi(optarg);
            break;
        case 'e':
            use_ecm = true;
            break;
        case 'F':
            fill_removal = true;
            break;
        case 'G':
            t38_terminal_operation = false;
            break;
        case 'i':
            input_file_name = optarg;
            break;
        case 'l':
            log_audio = true;
            break;
        case 'm':
            supported_modems = atoi(optarg);
            break;
        case 'o':
            options = atoi(optarg);
            break;
        case 'S':
            src_addr = parse_inet_addr(optarg);
            break;
        case 's':
            src_port = atoi(optarg);
            break;
        case 't':
            use_tep = true;
            break;
        case 'v':
            t38_version = atoi(optarg);
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    printf("Using T.38 version %d\n", t38_version);

    if (t38_terminal_operation)
    {
        if ((t38_terminal_state = t38_terminal_init(NULL, caller, tx_packet_handler, NULL)) == NULL)
        {
            fprintf(stderr, "Cannot start the T.38 channel\n");
            exit(2);
        }
        t30 = t38_terminal_get_t30_state(t38_terminal_state);
        t38_core = t38_terminal_get_t38_core_state(t38_terminal_state);
        t38_set_t38_version(t38_core, t38_version);
        t38_terminal_set_config(t38_terminal_state, options);
        t38_terminal_set_tep_mode(t38_terminal_state, use_tep);
        t38_terminal_set_fill_bit_removal(t38_terminal_state, fill_removal);

        logging = t38_terminal_get_logging_state(t38_terminal_state);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        logging = t38_core_get_logging_state(t38_core);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        logging = t30_get_logging_state(t30);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        t30_set_supported_modems(t30, supported_modems);
        t30_set_tx_ident(t30, "11111111");
        t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
        if (caller)
            t30_set_tx_file(t30, INPUT_TIFF_FILE_NAME, -1, -1);
        else
            t30_set_rx_file(t30, OUTPUT_TIFF_FILE_NAME, -1);
        t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'A');
        t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'A');
        t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'A');
        t30_set_ecm_capability(t30, use_ecm);
        t30_set_supported_compressions(t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6 | T4_COMPRESSION_T85);

        if (pcap_scan_pkts(input_file_name, src_addr, src_port, dest_addr, dest_port, t38_terminal_timing_update, process_packet, NULL))
            exit(2);
        /* Push the time along, to flush out any remaining activity from the application. */
        now.tv_sec += 60;
        t38_terminal_timing_update(NULL, &now);
    }
    else
    {
        wave_handle = NULL;
        if (log_audio)
        {
            if ((wave_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
            {
                fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
                exit(2);
            }
        }

        if ((t38_gateway_state = t38_gateway_init(NULL, tx_packet_handler, NULL)) == NULL)
        {
            fprintf(stderr, "Cannot start the T.38 channel\n");
            exit(2);
        }
        t38_core = t38_gateway_get_t38_core_state(t38_gateway_state);
        t38_gateway_set_transmit_on_idle(t38_gateway_state, use_transmit_on_idle);
        t38_set_t38_version(t38_core, t38_version);
        t38_gateway_set_ecm_capability(t38_gateway_state, use_ecm);

        logging = t38_gateway_get_logging_state(t38_gateway_state);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        logging = t38_core_get_logging_state(t38_core);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "T.38");

        if ((fax_state = fax_init(NULL, caller)) == NULL)
        {
            fprintf(stderr, "Cannot start FAX\n");
            exit(2);
        }
        t30 = fax_get_t30_state(fax_state);
        fax_set_transmit_on_idle(fax_state, use_transmit_on_idle);
        fax_set_tep_mode(fax_state, use_tep);
        t30_set_supported_modems(t30, supported_modems);
        t30_set_tx_ident(t30, "22222222");
        t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
        if (caller)
            t30_set_tx_file(t30, INPUT_TIFF_FILE_NAME, -1, -1);
        else
            t30_set_rx_file(t30, OUTPUT_TIFF_FILE_NAME, -1);
        t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) 'B');
        t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) 'B');
        t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) 'B');
        t30_set_ecm_capability(t30, use_ecm);
        t30_set_supported_compressions(t30, T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6);

        logging = fax_get_logging_state(fax_state);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "FAX ");

        logging = t30_get_logging_state(t30);
        span_log_set_level(logging, SPAN_LOG_DEBUG | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME);
        span_log_set_tag(logging, "FAX ");

        if (pcap_scan_pkts(input_file_name, src_addr, src_port, dest_addr, dest_port, t38_gateway_timing_update, process_packet, NULL))
            exit(2);
        /* Push the time along, to flush out any remaining activity from the application. */
        now.tv_sec += 60;
        t38_gateway_timing_update(NULL, &now);

        fax_release(fax_state);
        t38_gateway_release(t38_gateway_state);
        if (log_audio)
        {
            if (sf_close_telephony(wave_handle))
            {
                fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
                exit(2);
            }
        }
    }
}
static void compliance_tests(int log_audio)
{
    SNDFILE *outhandle;
    power_meter_t power_meter;
    int outframes;
    int i;
    int block;
    int pre;
    int post;
    int post_post;
    int alaw_failures;
    int ulaw_failures;
    float worst_alaw;
    float worst_ulaw;
    float tmp;
    int len;
    g711_state_t *enc_state;
    g711_state_t *transcode;
    g711_state_t *dec_state;

    outhandle = NULL;
    if (log_audio)
    {
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }

    printf("Conversion accuracy tests.\n");
    alaw_failures = 0;
    ulaw_failures = 0;
    worst_alaw = 0.0;
    worst_ulaw = 0.0;
    for (block = 0;  block < 1;  block++)
    {
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = alaw_to_linear(linear_to_alaw(pre));
            if (abs(pre) > 140)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
                if (tmp > worst_alaw)
                    worst_alaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 15)
                {
                    printf("A-law: Excessive error at %d (%d)\n", pre, post);
                    alaw_failures++;
                }
            }
            amp[i] = post;
        }
        if (log_audio)
        {
            outframes = sf_writef_short(outhandle, amp, 65536);
            if (outframes != 65536)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
        }
        for (i = 0;  i < 65536;  i++)
        {
            pre = i - 32768;
            post = ulaw_to_linear(linear_to_ulaw(pre));
            if (abs(pre) > 40)
            {
                tmp = (float) abs(post - pre)/(float) abs(pre);
                if (tmp > 0.10)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
                if (tmp > worst_ulaw)
                    worst_ulaw = tmp;
            }
            else
            {
                /* Small values need different handling for sensible measurement */
                if (abs(post - pre) > 4)
                {
                    printf("u-law: Excessive error at %d (%d)\n", pre, post);
                    ulaw_failures++;
                }
            }
            amp[i] = post;
        }
        if (log_audio)
        {
            outframes = sf_writef_short(outhandle, amp, 65536);
            if (outframes != 65536)
            {
                fprintf(stderr, "    Error writing audio file\n");
                exit(2);
            }
        }
    }
    printf("Worst A-law error (ignoring small values) %f%%\n", worst_alaw*100.0);
    printf("Worst u-law error (ignoring small values) %f%%\n", worst_ulaw*100.0);
    if (alaw_failures  ||  ulaw_failures)
    {
        printf("%d A-law values with excessive error\n", alaw_failures);
        printf("%d u-law values with excessive error\n", ulaw_failures);
        printf("Tests failed\n");
        exit(2);
    }

    printf("Cyclic conversion repeatability tests.\n");
    /* Find what happens to every possible linear value after a round trip. */
    for (i = 0;  i < 65536;  i++)
    {
        pre = i - 32768;
        /* Make a round trip */
        post = alaw_to_linear(linear_to_alaw(pre));
        /* A second round trip should cause no further change */
        post_post = alaw_to_linear(linear_to_alaw(post));
        if (post_post != post)
        {
            printf("A-law second round trip mismatch - at %d, %d != %d\n", pre, post, post_post);
            printf("Tests failed\n");
            exit(2);
        }
        /* Make a round trip */
        post = ulaw_to_linear(linear_to_ulaw(pre));
        /* A second round trip should cause no further change */
        post_post = ulaw_to_linear(linear_to_ulaw(post));
        if (post_post != post)
        {
            printf("u-law round trip mismatch - at %d, %d != %d\n", pre, post, post_post);
            printf("Tests failed\n");
            exit(2);
        }
    }

    printf("Reference power level tests.\n");
    power_meter_init(&power_meter, 7);

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = ulaw_to_linear(ulaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference u-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter));
    if (log_audio)
    {
        outframes = sf_writef_short(outhandle, amp, 8000);
        if (outframes != 8000)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }
    if (0.1f < fabs(power_meter_current_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    for (i = 0;  i < 8000;  i++)
    {
        amp[i] = alaw_to_linear(alaw_1khz_sine[i & 7]);
        power_meter_update(&power_meter, amp[i]);
    }
    printf("Reference A-law 1kHz tone is %fdBm0\n", power_meter_current_dbm0(&power_meter));
    if (log_audio)
    {
        outframes = sf_writef_short(outhandle, amp, 8000);
        if (outframes != 8000)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }
    if (0.1f < fabs(power_meter_current_dbm0(&power_meter)))
    {
        printf("Test failed.\n");
        exit(2);
    }

    /* Check the transcoding functions. */
    printf("Testing transcoding A-law -> u-law -> A-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (alaw_to_ulaw(ulaw_to_alaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("u-law -> A-law -> u-law gave %d -> %d\n", i, alaw_to_ulaw(ulaw_to_alaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    printf("Testing transcoding u-law -> A-law -> u-law\n");
    for (i = 0;  i < 256;  i++)
    {
        if (ulaw_to_alaw(alaw_to_ulaw(i)) != i)
        {
            if (abs(alaw_to_ulaw(ulaw_to_alaw(i)) - i) > 1)
            {
                printf("A-law -> u-law -> A-law gave %d -> %d\n", i, ulaw_to_alaw(alaw_to_ulaw(i)));
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    enc_state = g711_init(NULL, G711_ALAW);
    transcode = g711_init(NULL, G711_ALAW);
    dec_state = g711_init(NULL, G711_ULAW);

    len = 65536;
    for (i = 0;  i < len;  i++)
        amp[i] = i - 32768;
    len = g711_encode(enc_state, alaw_data, amp, len);
    len = g711_transcode(transcode, ulaw_data, alaw_data, len);
    len = g711_decode(dec_state, amp, ulaw_data, len);
    if (len != 65536)
    {
        printf("Block coding gave the wrong length - %d instead of %d\n", len, 65536);
        printf("Test failed\n");
        exit(2);
    }
    for (i = 0;  i < len;  i++)
    {
        pre = i - 32768;
        post = amp[i];
        if (abs(pre) > 140)
        {
            tmp = (float) abs(post - pre)/(float) abs(pre);
            if (tmp > 0.10)
            {
                printf("Block: Excessive error at %d (%d)\n", pre, post);
                exit(2);
            }
        }
        else
        {
            /* Small values need different handling for sensible measurement */
            if (abs(post - pre) > 15)
            {
                printf("Block: Excessive error at %d (%d)\n", pre, post);
                exit(2);
            }
        }
    }
    g711_release(enc_state);
    g711_release(transcode);
    g711_release(dec_state);

    if (log_audio)
    {
        if (sf_close_telephony(outhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }

    printf("Tests passed.\n");
}
int main(int argc, char *argv[])
{
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int frames;
    int bytes;
    int16_t pre_amp[HIST_LEN];
    int16_t post_amp[HIST_LEN];
    uint8_t gsm0610_data[HIST_LEN];
    gsm0610_state_t *gsm0610_enc_state;
    gsm0610_state_t *gsm0610_dec_state;
    int opt;
    int etsitests;
    int packing;

    etsitests = TRUE;
    packing = GSM0610_PACKING_NONE;
    while ((opt = getopt(argc, argv, "lp:")) != -1)
    {
        switch (opt)
        {
        case 'l':
            etsitests = FALSE;
            break;
        case 'p':
            packing = atoi(optarg);
            break;
        default:
            //usage();
            exit(2);
        }
    }

    if (etsitests)
    {
        etsi_compliance_tests();
    }
    else
    {
        if ((inhandle = sf_open_telephony_read(IN_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", IN_FILE_NAME);
            exit(2);
        }
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    
        if ((gsm0610_enc_state = gsm0610_init(NULL, packing)) == NULL)
        {
            fprintf(stderr, "    Cannot create encoder\n");
            exit(2);
        }
            
        if ((gsm0610_dec_state = gsm0610_init(NULL, packing)) == NULL)
        {
            fprintf(stderr, "    Cannot create decoder\n");
            exit(2);
        }

        while ((frames = sf_readf_short(inhandle, pre_amp, 2*BLOCK_LEN)))
        {
            bytes = gsm0610_encode(gsm0610_enc_state, gsm0610_data, pre_amp, frames);
            gsm0610_decode(gsm0610_dec_state, post_amp, gsm0610_data, bytes);
            sf_writef_short(outhandle, post_amp, frames);
        }
    
        if (sf_close_telephony(inhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", IN_FILE_NAME);
            exit(2);
        }
        if (sf_close_telephony(outhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
        gsm0610_release(gsm0610_enc_state);
        gsm0610_release(gsm0610_dec_state);
    }
    return 0;
}
Beispiel #20
0
static void dynamic_buffer_tests(void)
{
    playout_state_t *s;
    playout_frame_t frame;
    playout_frame_t *p;
    plc_state_t plc;
    time_scale_state_t ts;
    int16_t *amp;
    int16_t fill[BLOCK_LEN];
    int16_t buf[20*BLOCK_LEN];
    int16_t out[10*BLOCK_LEN];
    timestamp_t time_stamp;
    timestamp_t next_actual_receive;
    timestamp_t next_scheduled_receive;
    int near_far_time_offset;
    int rng;
    int i;
    int j;
    int ret;
    int len;
    int inframes;
    int outframes;
    SNDFILE *inhandle;
    SNDFILE *outhandle;

    if ((inhandle = sf_open_telephony_read(INPUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Failed to open audio file '%s'\n", INPUT_FILE_NAME);
        exit(2);
    }
    if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Failed to create audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    near_far_time_offset = 54321;
    time_stamp = 12345;
    next_actual_receive = time_stamp + near_far_time_offset;
    next_scheduled_receive = 0;
    for (i = 0;  i < BLOCK_LEN;  i++)
        fill[i] = 32767;

    if ((s = playout_init(2*BLOCK_LEN, 15*BLOCK_LEN)) == NULL)
        return;
    plc_init(&plc);
    time_scale_init(&ts, SAMPLE_RATE, 1.0);
    for (i = 0;  i < 1000000;  i++)
    {
        if (i >= next_actual_receive)
        {
            amp = malloc(BLOCK_LEN*sizeof(int16_t));
            inframes = sf_readf_short(inhandle, amp, BLOCK_LEN);
            if (inframes < BLOCK_LEN)
                break;
            ret = playout_put(s,
                              amp,
                              PLAYOUT_TYPE_SPEECH,
                              inframes,
                              time_stamp,
                              next_actual_receive);
#if 0
            switch (ret)
            {
            case PLAYOUT_OK:
                printf("<< Record\n");
                break;
            case PLAYOUT_ERROR:
                printf("<< Error\n");
                break;
            default:
                printf("<< Eh?\n");
                break;
            }
#endif
            rng = rand() & 0xFF;
            if (i < 100000)
                rng = (rng*rng) >> 7;
            else if (i < 200000)
                rng = (rng*rng) >> 6;
            else if (i < 300000)
Beispiel #21
0
int main(int argc, char *argv[])
{
    v17_rx_state_t *rx;
    v17_tx_state_t *tx;
    bert_results_t bert_results;
    int16_t gen_amp[BLOCK_LEN];
    int16_t amp[BLOCK_LEN];
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int outframes;
    int samples;
    int tep;
    int block_no;
    int noise_level;
    int signal_level;
    int bits_per_test;
    int line_model_no;
    int log_audio;
    int channel_codec;
    int rbs_pattern;
    int opt;
    logging_state_t *logging;

    channel_codec = MUNGE_CODEC_NONE;
    rbs_pattern = 0;
    test_bps = 14400;
    tep = FALSE;
    line_model_no = 0;
    decode_test_file = NULL;
    use_gui = FALSE;
    noise_level = -70;
    signal_level = -13;
    bits_per_test = 50000;
    log_audio = FALSE;
    while ((opt = getopt(argc, argv, "b:B:c:d:glm:n:r:s:t")) != -1)
    {
        switch (opt)
        {
        case 'b':
            test_bps = atoi(optarg);
            if (test_bps != 14400
                &&
                test_bps != 12000
                &&
                test_bps != 9600
                &&
                test_bps != 7200
                &&
                test_bps != 4800)
            {
                /* 4800 is an extension of V.17, to provide full coverage of the V.32bis modes */
                fprintf(stderr, "Invalid bit rate specified\n");
                exit(2);
            }
            break;
        case 'B':
            bits_per_test = atoi(optarg);
            break;
        case 'c':
            channel_codec = atoi(optarg);
            break;
        case 'd':
            decode_test_file = optarg;
            break;
        case 'g':
#if defined(ENABLE_GUI)
            use_gui = TRUE;
#else
            fprintf(stderr, "Graphical monitoring not available\n");
            exit(2);
#endif
            break;
        case 'l':
            log_audio = TRUE;
            break;
        case 'm':
            line_model_no = atoi(optarg);
            break;
        case 'n':
            noise_level = atoi(optarg);
            break;
        case 'r':
            rbs_pattern = atoi(optarg);
            break;
        case 's':
            signal_level = atoi(optarg);
            break;
        case 't':
            tep = TRUE;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }
    inhandle = NULL;
    outhandle = NULL;

#if defined(HAVE_FENV_H)
    fpe_trap_setup();
#endif

    if (log_audio)
    {
        if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }

    if (decode_test_file)
    {
        /* We will decode the audio from a file. */
        tx = NULL;
        if ((inhandle = sf_open_telephony_read(decode_test_file, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    else
    {
        /* We will generate V.17 audio, and add some noise to it. */
        tx = v17_tx_init(NULL, test_bps, tep, v17getbit, NULL);
        logging = v17_tx_get_logging_state(tx);
        span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
        span_log_set_tag(logging, "V.17-tx");
        v17_tx_power(tx, signal_level);
        v17_tx_set_modem_status_handler(tx, v17_tx_status, (void *) tx);
#if defined(WITH_SPANDSP_INTERNALS)
        /* Move the carrier off a bit */
        tx->carrier_phase_rate = dds_phase_ratef(1792.0f);
        tx->carrier_phase = 0x40000000;
#endif

        bert_init(&bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
        bert_set_report(&bert, 10000, reporter, NULL);

        if ((line_model = one_way_line_model_init(line_model_no, (float) noise_level, channel_codec, rbs_pattern)) == NULL)
        {
            fprintf(stderr, "    Failed to create line model\n");
            exit(2);
        }
        one_way_line_model_set_dc(line_model, 0.0f);
#if defined(ADD_MAINS_INTERFERENCE)
        one_way_line_model_set_mains_pickup(line_model, 50, -40.0f);
#endif
    }

    rx = v17_rx_init(NULL, test_bps, v17putbit, NULL);
    logging = v17_rx_get_logging_state(rx);
    span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
    span_log_set_tag(logging, "V.17-rx");
    v17_rx_set_modem_status_handler(rx, v17_rx_status, (void *) rx);
    v17_rx_set_qam_report_handler(rx, qam_report, (void *) rx);

#if defined(ENABLE_GUI)
    if (use_gui)
    {
        qam_monitor = qam_monitor_init(10.0f, NULL);
        if (!decode_test_file)
        {
            start_line_model_monitor(129);
            line_model_monitor_line_model_update(line_model->near_filter, line_model->near_filter_len);
        }
    }
#endif

    memset(&latest_results, 0, sizeof(latest_results));
    for (block_no = 0;  block_no < 100000000;  block_no++)
    {
        if (decode_test_file)
        {
            samples = sf_readf_short(inhandle, amp, BLOCK_LEN);
#if defined(ENABLE_GUI)
            if (use_gui)
                qam_monitor_update_audio_level(qam_monitor, amp, samples);
#endif
            if (samples == 0)
                break;
        }
        else
        {
            samples = v17_tx(tx, gen_amp, BLOCK_LEN);
#if defined(ENABLE_GUI)
            if (use_gui)
                qam_monitor_update_audio_level(qam_monitor, gen_amp, samples);
#endif
            if (samples == 0)
            {
                printf("Restarting on zero output\n");

                /* Push a little silence through, to ensure all the data bits get out of the buffers */
                vec_zeroi16(amp, BLOCK_LEN);
                v17_rx(rx, amp, BLOCK_LEN);

                /* Note that we might get a few bad bits as the carrier shuts down. */
                bert_result(&bert, &bert_results);
                fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
                fprintf(stderr, "Last report  %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
                /* See if bit errors are appearing yet. Also check we are getting enough bits out of the receiver. The last regular report
                   should be error free, though the final report will generally contain bits errors as the carrier was dying. The total
                   number of bits out of the receiver should be at least the number we sent. Also, since BERT sync should have occurred
                   rapidly at the start of transmission, the last report should have occurred at not much less than the total number of
                   bits we sent. */
                if (bert_results.total_bits < bits_per_test
                    ||
                    latest_results.total_bits < bits_per_test - 100
                    ||
                    latest_results.bad_bits != 0)
                {
                    break;
                }
                memset(&latest_results, 0, sizeof(latest_results));
#if defined(WITH_SPANDSP_INTERNALS)
                signal_level--;
                /* Bump the receiver AGC gain by 1dB, to compensate for the above */
                rx->agc_scaling_save *= 1.122f;
#endif
                v17_tx_restart(tx, test_bps, tep, TRUE);
                v17_tx_power(tx, signal_level);
                v17_rx_restart(rx, test_bps, TRUE);
                //rx.eq_put_step = rand()%(192*10/3);
                bert_init(&bert, bits_per_test, BERT_PATTERN_ITU_O152_11, test_bps, 20);
                bert_set_report(&bert, 10000, reporter, NULL);
                one_way_line_model_release(line_model);
                if ((line_model = one_way_line_model_init(line_model_no, (float) noise_level, channel_codec, 0)) == NULL)
                {
                    fprintf(stderr, "    Failed to create line model\n");
                    exit(2);
                }
            }
            if (log_audio)
            {
                outframes = sf_writef_short(outhandle, gen_amp, samples);
                if (outframes != samples)
                {
                    fprintf(stderr, "    Error writing audio file\n");
                    exit(2);
                }
            }
            one_way_line_model(line_model, amp, gen_amp, samples);
        }
#if defined(ENABLE_GUI)
        if (use_gui  &&  !decode_test_file)
            line_model_monitor_line_spectrum_update(amp, samples);
#endif
        v17_rx(rx, amp, samples);
    }
    if (!decode_test_file)
    {
        bert_result(&bert, &bert_results);
        fprintf(stderr, "At completion:\n");
        fprintf(stderr, "Final result %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, bert_results.total_bits, bert_results.bad_bits, bert_results.resyncs);
        fprintf(stderr, "Last report  %ddBm0/%ddBm0, %d bits, %d bad bits, %d resyncs\n", signal_level, noise_level, latest_results.total_bits, latest_results.bad_bits, latest_results.resyncs);
        one_way_line_model_release(line_model);

        if (signal_level > -43)
        {
            printf("Tests failed.\n");
            exit(2);
        }

        printf("Tests passed.\n");
    }
#if defined(ENABLE_GUI)
    if (use_gui)
        qam_wait_to_end(qam_monitor);
#endif
    if (decode_test_file)
    {
        if (sf_close_telephony(inhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", decode_test_file);
            exit(2);
        }
    }
    if (log_audio)
    {
        if (sf_close_telephony(outhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
            exit(2);
        }
    }
    return  0;
}
int main(int argc, char *argv[])
{
    SNDFILE *inhandle;
    SNDFILE *refhandle;
    SNDFILE *outhandle;
    int frames;
    double pre_energy;
    double post_energy;
    double ref_energy;
    double diff_energy;
    int16_t pre_amp[BLOCKS_PER_READ*BLOCK_LEN];
    int16_t post_amp[BLOCKS_PER_READ*BLOCK_LEN];
    int16_t ref_amp[BLOCKS_PER_READ*BLOCK_LEN];
    int16_t log_amp[BLOCKS_PER_READ*BLOCK_LEN*3];
    uint8_t lpc10_data[BLOCKS_PER_READ*7];
    double xx;
    lpc10_encode_state_t *lpc10_enc_state;
    lpc10_decode_state_t *lpc10_dec_state;
    int i;
    int block_no;
    int log_error;
    int compress;
    int decompress;
    const char *in_file_name;
    int compress_file;
    int decompress_file;
    int len;
    int opt;
    int enc_len;
    int dec_len;

    compress = FALSE;
    decompress = FALSE;
    log_error = TRUE;
    in_file_name = IN_FILE_NAME;
    while ((opt = getopt(argc, argv, "cdi:l")) != -1)
    {
        switch (opt)
        {
        case 'c':
            compress = TRUE;
            break;
        case 'd':
            decompress = TRUE;
            break;
        case 'i':
            in_file_name = optarg;
            break;
        case 'l':
            log_error = FALSE;
            break;
        default:
            //usage();
            exit(2);
        }
    }

    compress_file = -1;
    decompress_file = -1;
    inhandle = NULL;
    refhandle = NULL;
    outhandle = NULL;
    if (!decompress)
    {
        if ((inhandle = sf_open_telephony_read(in_file_name, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", in_file_name);
            exit(2);
        }

        if ((refhandle = sf_open_telephony_read(REF_FILE_NAME, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", REF_FILE_NAME);
            exit(2);
        }
    }
    else
    {
        if ((decompress_file = open(DECOMPRESS_FILE_NAME, O_RDONLY)) < 0)
        {
            fprintf(stderr, "    Cannot open decompressed data file '%s'\n", DECOMPRESS_FILE_NAME);
            exit(2);
        }
    }

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    
    if ((lpc10_enc_state = lpc10_encode_init(NULL, TRUE)) == NULL)
    {
        fprintf(stderr, "    Cannot create encoder\n");
        exit(2);
    }
            
    if ((lpc10_dec_state = lpc10_decode_init(NULL, TRUE)) == NULL)
    {
        fprintf(stderr, "    Cannot create decoder\n");
        exit(2);
    }

    if (compress)
    {
        if ((compress_file = open(COMPRESS_FILE_NAME, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
        {
            fprintf(stderr, "    Cannot create compressed data file '%s'\n", COMPRESS_FILE_NAME);
            exit(2);
        }
    }

    pre_energy = 0.0;
    post_energy = 0.0;
    ref_energy = 0.0;
    diff_energy = 0.0;

    if (decompress)
    {
        while ((len = read(decompress_file, lpc10_data, BLOCKS_PER_READ*7)) > 0)
        {
            lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, len/7);
            sf_writef_short(outhandle, post_amp, BLOCK_LEN*len/7);
        }
    }
    else
    {
        block_no = 0;
        while ((frames = sf_readf_short(inhandle, pre_amp, BLOCKS_PER_READ*BLOCK_LEN)) == BLOCKS_PER_READ*BLOCK_LEN
                &&
                (frames = sf_readf_short(refhandle, ref_amp, BLOCKS_PER_READ*BLOCK_LEN)) == BLOCKS_PER_READ*BLOCK_LEN)
        {
            enc_len = lpc10_encode(lpc10_enc_state, lpc10_data, pre_amp, BLOCKS_PER_READ*BLOCK_LEN);
            if (compress)
                write(compress_file, lpc10_data, enc_len);
            dec_len = lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, enc_len);
            for (i = 0;  i < dec_len;  i++)
            {
                pre_energy += (double) pre_amp[i]*(double) pre_amp[i];
                post_energy += (double) post_amp[i]*(double) post_amp[i];
                ref_energy += (double) ref_amp[i]*(double) ref_amp[i];
                /* The reference file has some odd clipping, so eliminate this from the
                   energy measurement. */
                if (ref_amp[i] == 32767  ||  ref_amp[i] == -32768)
                    xx = 0.0;
                else
                    xx = post_amp[i] - ref_amp[i];
                diff_energy += (double) xx*(double) xx;
                log_amp[i] = xx;
            }
            block_no++;
            if (log_error)
                sf_writef_short(outhandle, log_amp, dec_len);
            else
                sf_writef_short(outhandle, post_amp, dec_len);
        }
        if (sf_close_telephony(inhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", in_file_name);
            exit(2);
        }
        if (sf_close_telephony(refhandle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", REF_FILE_NAME);
            exit(2);
        }
    }
    
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    if (compress)
        close(compress_file);
    if (decompress)
        close(decompress_file);
    lpc10_encode_release(lpc10_enc_state);
    lpc10_decode_release(lpc10_dec_state);

    if (!decompress)
    {
        printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy);
        printf("Difference energy is %f%% of the total.\n", 100.0*diff_energy/ref_energy);
        if (fabs(1.0 - post_energy/pre_energy) > 0.05
            ||
            fabs(diff_energy/post_energy) > 0.03)
        {
            printf("Tests failed.\n");
            exit(2);
        }
        printf("Tests passed.\n");
    }
    return 0;
}
Beispiel #23
0
int main(int argc, char *argv[])
{
    SNDFILE *wave_handle;
    SNDFILE *input_wave_handle;
    int i;
    int j;
    int k;
    struct machine_s *mc;
    int outframes;
    char buf[128 + 1];
    int16_t silence[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    int alldone;
    const char *input_tiff_file_name;
    const char *input_audio_file_name;
    int log_audio;
    int use_ecm;
    int use_tep;
    int use_transmit_on_idle;
#if defined(WITH_SPANDSP_INTERNALS)
    int use_line_hits;
#endif
    int polled_mode;
    int reverse_flow;
    int use_page_limits;
    int supported_modems;
    int signal_level;
    int noise_level;
    float signal_scaling;
    time_t start_time;
    time_t end_time;
    int scan_line_time;
    char *page_header_info;
    int opt;
    t30_state_t *t30;
    logging_state_t *logging;

    log_audio = false;
    input_tiff_file_name = INPUT_TIFF_FILE_NAME;
    input_audio_file_name = NULL;
    use_ecm = false;
#if defined(WITH_SPANDSP_INTERNALS)
    use_line_hits = false;
#endif
    use_tep = false;
    polled_mode = false;
    page_header_info = NULL;
    reverse_flow = false;
    use_transmit_on_idle = true;
    use_receiver_not_ready = false;
    use_page_limits = false;
    signal_level = 0;
    noise_level = -99;
    scan_line_time = 0;
    supported_modems = T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17;
    while ((opt = getopt(argc, argv, "ehH:i:I:lm:n:prRs:S:tTw:")) != -1)
    {
        switch (opt)
        {
        case 'e':
            use_ecm = true;
            break;
#if defined(WITH_SPANDSP_INTERNALS)
        case 'h':
            use_line_hits = true;
            break;
#endif
        case 'H':
            page_header_info = optarg;
            break;
        case 'i':
            input_tiff_file_name = optarg;
            break;
        case 'I':
            input_audio_file_name = optarg;
            break;
        case 'l':
            log_audio = true;
            break;
        case 'm':
            supported_modems = atoi(optarg);
            break;
        case 'n':
            noise_level = atoi(optarg);
            break;
        case 'p':
            polled_mode = true;
            break;
        case 'r':
            reverse_flow = true;
            break;
        case 'R':
            use_receiver_not_ready = true;
            break;
        case 's':
            signal_level = atoi(optarg);
            break;
        case 'S':
            scan_line_time = atoi(optarg);
            break;
        case 't':
            use_tep = true;
            break;
        case 'T':
            use_page_limits = true;
            break;
        case 'w':
            t30_state_to_wreck = atoi(optarg);
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    input_wave_handle = NULL;
    if (input_audio_file_name)
    {
        if ((input_wave_handle = sf_open_telephony_read(input_audio_file_name, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", input_audio_file_name);
            exit(2);
        }
    }

    wave_handle = NULL;
    if (log_audio)
    {
        if ((wave_handle = sf_open_telephony_write(OUTPUT_FILE_NAME_WAVE, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
            exit(2);
        }
    }

    memset(silence, 0, sizeof(silence));
    for (j = 0;  j < FAX_MACHINES;  j++)
    {
        machines[j].chan = j;
        mc = &machines[j];

        i = mc->chan + 1;
        sprintf(buf, "%d%d%d%d%d%d%d%d", i, i, i, i, i, i, i, i);
        if (reverse_flow)
            mc->fax = fax_init(NULL, (mc->chan & 1)  ?  true  :  false);
        else
            mc->fax = fax_init(NULL, (mc->chan & 1)  ?  false  :  true);
        mc->awgn = NULL;
        signal_scaling = 1.0f;
        if (noise_level > -99)
        {
            mc->awgn = awgn_init_dbm0(NULL, 1234567, noise_level);
            signal_scaling = powf(10.0f, signal_level/20.0f);
            printf("Signal scaling %f\n", signal_scaling);
        }
        fax_set_transmit_on_idle(mc->fax, use_transmit_on_idle);
        fax_set_tep_mode(mc->fax, use_tep);
        t30 = fax_get_t30_state(mc->fax);
        t30_set_tx_ident(t30, buf);
        t30_set_tx_sub_address(t30, "Sub-address");
        t30_set_tx_sender_ident(t30, "Sender ID");
        t30_set_tx_password(t30, "Password");
        t30_set_tx_polled_sub_address(t30, "Polled sub-address");
        t30_set_tx_selective_polling_address(t30, "Selective polling address");
        t30_set_tx_page_header_info(t30, page_header_info);
        t30_set_tx_nsf(t30, (const uint8_t *) "\x50\x00\x00\x00Spandsp\x00", 12);
        t30_set_ecm_capability(t30, use_ecm);
        t30_set_supported_t30_features(t30,
                                       T30_SUPPORT_IDENTIFICATION
                                     | T30_SUPPORT_SELECTIVE_POLLING
                                     | T30_SUPPORT_SUB_ADDRESSING);

        if ((mc->chan & 1))
            t30_set_minimum_scan_line_time(t30, scan_line_time);
        t30_set_supported_image_sizes(t30,
                                      T30_SUPPORT_US_LETTER_LENGTH
                                    | T30_SUPPORT_US_LEGAL_LENGTH
                                    | T30_SUPPORT_UNLIMITED_LENGTH
                                    | T30_SUPPORT_215MM_WIDTH
                                    | T30_SUPPORT_255MM_WIDTH
                                    | T30_SUPPORT_303MM_WIDTH);
        t30_set_supported_resolutions(t30,
                                      T30_SUPPORT_STANDARD_RESOLUTION
                                    | T30_SUPPORT_FINE_RESOLUTION
                                    | T30_SUPPORT_SUPERFINE_RESOLUTION
                                    | T30_SUPPORT_R8_RESOLUTION
                                    | T30_SUPPORT_R16_RESOLUTION
                                    | T30_SUPPORT_300_300_RESOLUTION
                                    | T30_SUPPORT_400_400_RESOLUTION
                                    | T30_SUPPORT_600_600_RESOLUTION
                                    | T30_SUPPORT_1200_1200_RESOLUTION
                                    | T30_SUPPORT_300_600_RESOLUTION
                                    | T30_SUPPORT_400_800_RESOLUTION
                                    | T30_SUPPORT_600_1200_RESOLUTION);
        t30_set_supported_modems(t30, supported_modems);
        if (use_ecm)
#if defined(SPANDSP_SUPPORT_T85)
            t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T85_COMPRESSION);
#else
            t30_set_supported_compressions(t30, T30_SUPPORT_T4_1D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
#endif
        if ((mc->chan & 1))
        {
            if (polled_mode)
            {
                if (use_page_limits)
                    t30_set_tx_file(t30, input_tiff_file_name, 3, 6);
                else
                    t30_set_tx_file(t30, input_tiff_file_name, -1, -1);
            }
            else
            {
                sprintf(buf, "fax_tests_%d.tif", (mc->chan + 1)/2);
                t30_set_rx_file(t30, buf, -1);
                t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T6);
            }
        }
        else
        {
            if (polled_mode)
            {
                sprintf(buf, "fax_tests_%d.tif", (mc->chan + 1)/2);
                t30_set_rx_file(t30, buf, -1);
                t30_set_rx_encoding(t30, T4_COMPRESSION_ITU_T6);
            }
            else
            {
                if (use_page_limits)
                    t30_set_tx_file(t30, input_tiff_file_name, 3, 6);
                else
                    t30_set_tx_file(t30, input_tiff_file_name, -1, -1);
            }
        }
        t30_set_phase_b_handler(t30, phase_b_handler, (void *) (intptr_t) mc->chan + 'A');
        t30_set_phase_d_handler(t30, phase_d_handler, (void *) (intptr_t) mc->chan + 'A');
        t30_set_phase_e_handler(t30, phase_e_handler, (void *) (intptr_t) mc->chan + 'A');
        t30_set_real_time_frame_handler(t30, real_time_frame_handler, (void *) (intptr_t) mc->chan + 'A');
        t30_set_document_handler(t30, document_handler, (void *) (intptr_t) mc->chan + 'A');
        sprintf(mc->tag, "FAX-%d", j + 1);

        logging = t30_get_logging_state(t30);
        span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
        span_log_set_tag(logging, mc->tag);
        if ((j & 1))
        {
            span_log_set_level(&t30->t4.rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
            span_log_set_tag(&t30->t4.rx.logging, mc->tag);
        }
        else
        {
            span_log_set_level(&t30->t4.tx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
            span_log_set_tag(&t30->t4.tx.logging, mc->tag);
        }
        logging = fax_get_logging_state(mc->fax);
        span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
        span_log_set_tag(logging, mc->tag);

        memset(mc->amp, 0, sizeof(mc->amp));
        mc->total_audio_time = 0;
        mc->done = false;
    }
    time(&start_time);
    for (;;)
    {
        alldone = true;
        for (j = 0;  j < FAX_MACHINES;  j++)
        {
            mc = &machines[j];

            if ((j & 1) == 0  &&  input_audio_file_name)
            {
                mc->len = sf_readf_short(input_wave_handle, mc->amp, SAMPLES_PER_CHUNK);
                if (mc->len == 0)
                    break;
            }
            else
            {
                mc->len = fax_tx(mc->fax, mc->amp, SAMPLES_PER_CHUNK);
                if (mc->awgn)
                {
                    for (k = 0;  k < mc->len;  k++)
                        mc->amp[k] = ((int16_t) (mc->amp[k]*signal_scaling)) + awgn(mc->awgn);
                }
            }
            mc->total_audio_time += SAMPLES_PER_CHUNK;
            if (!use_transmit_on_idle)
            {
                /* The receive side always expects a full block of samples, but the
                   transmit side may not be sending any when it doesn't need to. We
                   may need to pad with some silence. */
                if (mc->len < SAMPLES_PER_CHUNK)
                {
                    memset(mc->amp + mc->len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - mc->len));
                    mc->len = SAMPLES_PER_CHUNK;
                }
            }
            t30 = fax_get_t30_state(mc->fax);
            logging = t30_get_logging_state(t30);
            span_log_bump_samples(logging, mc->len);
            logging = fax_get_logging_state(mc->fax);
            span_log_bump_samples(logging, mc->len);

            if (log_audio)
            {
                for (k = 0;  k < mc->len;  k++)
                    out_amp[2*k + j] = mc->amp[k];
            }
            if (machines[j ^ 1].len < SAMPLES_PER_CHUNK)
                memset(machines[j ^ 1].amp + machines[j ^ 1].len, 0, sizeof(int16_t)*(SAMPLES_PER_CHUNK - machines[j ^ 1].len));
            t30 = fax_get_t30_state(mc->fax);
#if defined(WITH_SPANDSP_INTERNALS)
            if (use_line_hits)
            {
                /* TODO: This applies very crude line hits. improve it */
                if (t30->state == 22)
                {
                    if (++mc->error_delay == 100)
                    {
                        fprintf(stderr, "HIT %d!\n", j);
                        mc->error_delay = 0;
                        for (k = 0;  k < 5;  k++)
                            mc->amp[k] = 0;
                    }
                }
            }
            if (t30->state == t30_state_to_wreck)
                memset(machines[j ^ 1].amp, 0, sizeof(int16_t)*SAMPLES_PER_CHUNK);
#endif
            if (fax_rx(mc->fax, machines[j ^ 1].amp, SAMPLES_PER_CHUNK))
                break;
            if (!mc->done)
                alldone = false;
        }

        if (log_audio)
        {
            outframes = sf_writef_short(wave_handle, out_amp, SAMPLES_PER_CHUNK);
            if (outframes != SAMPLES_PER_CHUNK)
                break;
        }

        if (alldone  ||  j < FAX_MACHINES)
            break;
    }
    time(&end_time);
    for (j = 0;  j < FAX_MACHINES;  j++)
    {
        mc = &machines[j];
        fax_release(mc->fax);
    }
    if (log_audio)
    {
        if (sf_close(wave_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME_WAVE);
            exit(2);
        }
    }
    if (input_audio_file_name)
    {
        if (sf_close(input_wave_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", input_audio_file_name);
            exit(2);
        }
    }
    printf("Total audio time = %ds (wall time %ds)\n", machines[0].total_audio_time/8000, (int) (end_time - start_time));
    return 0;
}
Beispiel #24
0
int main(int argc, char *argv[])
{
    dtmf_tx_state_t *gen;
    int16_t amp[16384];
    int len;
    SNDFILE *outhandle;
    int add_digits;

    if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    gen = dtmf_tx_init(NULL, NULL, NULL);
    len = dtmf_tx(gen, amp, 16384);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "123", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 16384);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "456", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "789", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "*#", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    add_digits = 1;
    do
    {
        len = dtmf_tx(gen, amp, 160);
        printf("Generated %d samples\n", len);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
        if (add_digits)
        {
            if (dtmf_tx_put(gen, "1234567890", -1))
            {
                printf("Digit buffer full\n");
                add_digits = 0;
            }
        }
    }
    while (len > 0);

    dtmf_tx_init(gen, NULL, NULL);
    len = dtmf_tx(gen, amp, 16384);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "123", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 16384);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "456", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "789", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "0*#", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);
    if (dtmf_tx_put(gen, "ABCD", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    len = dtmf_tx(gen, amp, 160);
    printf("Generated %d samples\n", len);
    sf_writef_short(outhandle, amp, len);

    /* Try modifying the level and length of the digits */
    printf("Try different levels and timing\n");
    dtmf_tx_set_level(gen, -20, 5);
    dtmf_tx_set_timing(gen, 100, 200);
    if (dtmf_tx_put(gen, "123", -1))
    {
        printf("Ooops\n");
        exit(2);
    }
    do
    {
        len = dtmf_tx(gen, amp, 160);
        printf("Generated %d samples\n", len);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
    }
    while (len > 0);
    printf("Restore normal levels and timing\n");
    dtmf_tx_set_level(gen, -10, 0);
    dtmf_tx_set_timing(gen, 50, 55);
    if (dtmf_tx_put(gen, "A", -1))
    {
        printf("Ooops\n");
        exit(2);
    }

    add_digits = TRUE;
    do
    {
        len = dtmf_tx(gen, amp, 160);
        printf("Generated %d samples\n", len);
        if (len > 0)
            sf_writef_short(outhandle, amp, len);
        if (add_digits)
        {
            if (dtmf_tx_put(gen, "1234567890", -1))
            {
                printf("Digit buffer full\n");
                add_digits = FALSE;
            }
        }
    }
    while (len > 0);

    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    return 0;
}
int main (int argc, char *argv[])
{
    int i;
    int j;
    int level;
    int clip_high;
    int clip_low;
    int quality;
    int total_samples;
    int seed = 1234567;
    int outframes;
    int16_t value;
    double total;
    double x;
    double p;
    double o;
    int bins[65536];
    int16_t amp[1024];
    noise_state_t noise_source;
    SNDFILE *outhandle;

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }

    for (quality = 7;  quality <= 20;  quality += (20 - 7))
    {
        /* Generate AWGN at several RMS levels between -50dBOv and 0dBOv. Noise is
           generated for a large number of samples (1,000,000), and the RMS value
           of the noise is calculated along the way. If the resulting level is
           close to the requested RMS level, at least the scaling of the noise
           should be Ok. At high levels some clipping may distort the result a
           little. */
        printf("Testing AWGN power, with quality %d\n", quality);
        for (level = -50;  level <= 0;  level += 5)
        {
            clip_high = 0;
            clip_low = 0;
            total = 0.0;
            noise_init_dbov(&noise_source, seed, (float) level, NOISE_CLASS_AWGN, quality);
            total_samples = 1000000;
            for (i = 0;  i < total_samples;  i++)
            {
                value = noise(&noise_source);
                if (value == 32767)
                    clip_high++;
                else if (value == -32768)
                    clip_low++;
                total += ((double) value)*((double) value);
            }
            printf ("RMS = %.3f (expected %d) %.2f%% error [clipped samples %d+%d]\n",
                    log10(sqrt(total/total_samples)/32768.0)*20.0,
                    level,
                    100.0*(1.0 - sqrt(total/total_samples)/(pow(10.0, level/20.0)*32768.0)),
                    clip_low,
                    clip_high);
            if (level < -5  &&  fabs(log10(sqrt(total/total_samples)/32768.0)*20.0 - level) > 0.2)
            {
                printf("Test failed\n");
                exit(2);
            }
        }
    }

    /* Now look at the statistical spread of the results, by collecting data in
       bins from a large number of samples. Use a fairly high noise level, but
       low enough to avoid significant clipping. Use the Gaussian model to
       predict the real probability, and present the results for graphing. */
    quality = 7;
    printf("Testing the statistical spread of AWGN, with quality %d\n", quality);
    memset(bins, 0, sizeof(bins));
    clip_high = 0;
    clip_low = 0;
    level = -15;
    noise_init_dbov(&noise_source, seed, (float) level, NOISE_CLASS_AWGN, quality);
    total_samples = 10000000;
    for (i = 0;  i < total_samples;  i++)
    {
        value = noise(&noise_source);
        if (value == 32767)
            clip_high++;
        else if (value == -32768)
            clip_low++;
        bins[value + 32768]++;
    }
    /* Find the RMS power level to expect */
    o = pow(10.0, level/20.0)*(32768.0*0.70711);
    for (i = 0;  i < 65536 - 10;  i++)
    {
        x = i - 32768;
        /* Find the real probability for this bin */
        p = (1.0/(o*sqrt(2.0*M_PI)))*exp(-(x*x)/(2.0*o*o));
        /* Now do a little smoothing on the real data to get a reasonably
           steady answer */
        x = 0;
        for (j = 0;  j < 10;  j++)
            x += bins[i + j];
        x /= 10.0;
        x /= total_samples;
        /* Now send it out for graphing. */
        if (p > 0.0000001)
            printf("%6d %.7f %.7f\n", i - 32768, x, p);
    }

    printf("Generating AWGN at -15dBOv to file\n");
    for (j = 0;  j < 50;  j++)
    {
        for (i = 0;  i < 1024;  i++)
            amp[i] = noise(&noise_source);
        outframes = sf_writef_short(outhandle, amp, 1024);
        if (outframes != 1024)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }

    /* Generate Hoth noise at several RMS levels between -50dBm and 0dBm. Noise
       is generated for a large number of samples (1,000,000), and the RMS value
       of the noise is calculated along the way. If the resulting level is
       close to the requested RMS level, at least the scaling of the noise
       should be Ok. At high levels some clipping may distort the result a
       little. */
    quality = 7;
    printf("Testing Hoth noise power, with quality %d\n", quality);
    for (level = -50;  level <= 0;  level += 5)
    {
        clip_high = 0;
        clip_low = 0;
        total = 0.0;
        noise_init_dbov(&noise_source, seed, (float) level, NOISE_CLASS_HOTH, quality);
        total_samples = 1000000;
        for (i = 0;  i < total_samples;  i++)
        {
            value = noise(&noise_source);
            if (value == 32767)
                clip_high++;
            else if (value == -32768)
                clip_low++;
            total += ((double) value)*((double) value);
        }
        printf ("RMS = %.3f (expected %d) %.2f%% error [clipped samples %d+%d]\n",
                log10(sqrt(total/total_samples)/32768.0)*20.0,
                level,
                100.0*(1.0 - sqrt(total/total_samples)/(pow(10.0, level/20.0)*32768.0)),
                clip_low,
                clip_high);
        if (level < -5  &&  fabs(log10(sqrt(total/total_samples)/32768.0)*20.0 - level) > 0.2)
        {
            printf("Test failed\n");
            exit(2);
        }
    }

    quality = 7;
    printf("Generating Hoth noise at -15dBOv to file\n");
    level = -15;
    noise_init_dbov(&noise_source, seed, (float) level, NOISE_CLASS_HOTH, quality);
    for (j = 0;  j < 50;  j++)
    {
        for (i = 0;  i < 1024;  i++)
            amp[i] = noise(&noise_source);
        outframes = sf_writef_short(outhandle, amp, 1024);
        if (outframes != 1024)
        {
            fprintf(stderr, "    Error writing audio file\n");
            exit(2);
        }
    }

    if (sf_close(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }

    printf("Tests passed.\n");
    return  0;
}
Beispiel #26
0
static void exchange(faxtester_state_t *s)
{
    int16_t amp[SAMPLES_PER_CHUNK];
    int16_t out_amp[2*SAMPLES_PER_CHUNK];
    int len;
    int i;
    int total_audio_time;
    logging_state_t *logging;

    output_tiff_file_name = OUTPUT_TIFF_FILE_NAME;

    if (log_audio)
    {
        if ((out_handle = sf_open_telephony_write(OUTPUT_WAVE_FILE_NAME, 2)) == NULL)
        {
            fprintf(stderr, "    Cannot create audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            printf("Test failed\n");
            exit(2);
        }
        /*endif*/
    }
    /*endif*/

    total_audio_time = 0;

    faxtester_set_transmit_on_idle(s, true);

    s->far_fax = fax_init(NULL, false);
    s->far_t30 = fax_get_t30_state(s->far_fax);
    s->far_tag = 'A';

    if (s->far_fax)
        logging = fax_get_logging_state(s->far_fax);
    else
        logging = t38_terminal_get_logging_state(s->far_t38);
    span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
    span_log_set_tag(logging, "A");

    logging = t30_get_logging_state(s->far_t30);
    span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
    span_log_set_tag(logging, "A");

#if 0
    span_log_set_level(&fax.modems.v27ter_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
    span_log_set_tag(&fax.modems.v27ter_rx.logging, "A");
    span_log_set_level(&fax.modems.v29_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
    span_log_set_tag(&fax.modems.v29_rx.logging, "A");
    span_log_set_level(&fax.modems.v17_rx.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW);
    span_log_set_tag(&fax.modems.v17_rx.logging, "A");
#endif
    while (faxtester_next_step(s) == 0)
        ;
    /*endwhile*/
    for (;;)
    {
        len = fax_tx(s->far_fax, amp, SAMPLES_PER_CHUNK);
        faxtester_rx(s, amp, len);
        if (log_audio)
        {
            for (i = 0;  i < len;  i++)
                out_amp[2*i + 0] = amp[i];
            /*endfor*/
        }
        /*endif*/

        total_audio_time += SAMPLES_PER_CHUNK;

        logging = t30_get_logging_state(s->far_t30);
        span_log_bump_samples(logging, len);
#if 0
        span_log_bump_samples(&fax.modems.v27ter_rx.logging, len);
        span_log_bump_samples(&fax.modems.v29_rx.logging, len);
        span_log_bump_samples(&fax.modems.v17_rx.logging, len);
#endif
        logging = fax_get_logging_state(s->far_fax);
        span_log_bump_samples(logging, len);

        logging = faxtester_get_logging_state(s);
        span_log_bump_samples(logging, len);

        len = faxtester_tx(s, amp, SAMPLES_PER_CHUNK);
        if (fax_rx(s->far_fax, amp, len))
            break;
        /*endif*/
        if (log_audio)
        {
            for (i = 0;  i < len;  i++)
                out_amp[2*i + 1] = amp[i];
            /*endfor*/
            if (sf_writef_short(out_handle, out_amp, SAMPLES_PER_CHUNK) != SAMPLES_PER_CHUNK)
                break;
            /*endif*/
        }
        /*endif*/
        if (s->test_for_call_clear  &&  !s->far_end_cleared_call)
        {
            s->call_clear_timer += len;
            if (!t30_call_active(s->far_t30))
            {
                span_log(faxtester_get_logging_state(s), SPAN_LOG_FLOW, "Far end cleared after %dms (limits %dms to %dms)\n", s->call_clear_timer/8, s->timein_x, s->timeout);
                if (s->call_clear_timer/8 < s->timein_x  ||  s->call_clear_timer/8 > s->timeout_x)
                {
                    printf("Test failed\n");
                    exit(2);
                }
                span_log(faxtester_get_logging_state(s), SPAN_LOG_FLOW, "Clear time OK\n");
                s->far_end_cleared_call = true;
                s->test_for_call_clear = false;
                while (faxtester_next_step(s) == 0)
                    ;
                /*endwhile*/
            }
            /*endif*/
        }
        /*endif*/
    }
    /*endfor*/
    if (log_audio)
    {
        if (sf_close_telephony(out_handle))
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_WAVE_FILE_NAME);
            printf("Test failed\n");
            exit(2);
        }
        /*endif*/
    }
    /*endif*/
}
Beispiel #27
0
int main(int argc, char *argv[])
{
    int i;
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int frames;
    int dec_frames;
    int outframes;
    int ima_bytes;
    double pre_energy;
    double post_energy;
    double diff_energy;
    int16_t pre_amp[HIST_LEN];
    int16_t post_amp[HIST_LEN];
    uint8_t ima_data[HIST_LEN];
    int16_t history[HIST_LEN];
    int hist_in;
    int hist_out;
    ima_adpcm_state_t *ima_enc_state;
    ima_adpcm_state_t *ima_dec_state;
    int xx;
    int total_pre_samples;
    int total_compressed_bytes;
    int total_post_samples;
    const char *in_file_name;
    int variant;
    int chunk_size;
    int enc_chunk_size;
    int log_encoded_data;
    int opt;

    variant = IMA_ADPCM_DVI4;
    in_file_name = IN_FILE_NAME;
    chunk_size = 160;
    enc_chunk_size = 0;
    log_encoded_data = FALSE;
    while ((opt = getopt(argc, argv, "ac:i:lv")) != -1)
    {
        switch (opt)
        {
        case 'a':
            variant = IMA_ADPCM_IMA4;
            chunk_size = 505;
            break;
        case 'c':
            enc_chunk_size = atoi(optarg);
            break;
        case 'i':
            in_file_name = optarg;
            break;
        case 'l':
            log_encoded_data = TRUE;
            break;
        case 'v':
            variant = IMA_ADPCM_VDVI;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    if ((inhandle = sf_open_telephony_read(in_file_name, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", in_file_name);
        exit(2);
    }

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }

    if ((ima_enc_state = ima_adpcm_init(NULL, variant, enc_chunk_size)) == NULL)
    {
        fprintf(stderr, "    Cannot create encoder\n");
        exit(2);
    }
        
    if ((ima_dec_state = ima_adpcm_init(NULL, variant, enc_chunk_size)) == NULL)
    {
        fprintf(stderr, "    Cannot create decoder\n");
        exit(2);
    }

    hist_in = 0;
    hist_out = 0;
    pre_energy = 0.0;
    post_energy = 0.0;
    diff_energy = 0.0;
    total_pre_samples = 0;
    total_compressed_bytes = 0;
    total_post_samples = 0;
    while ((frames = sf_readf_short(inhandle, pre_amp, chunk_size)))
    {
        total_pre_samples += frames;
        ima_bytes = ima_adpcm_encode(ima_enc_state, ima_data, pre_amp, frames);
        if (log_encoded_data)
            write(1, ima_data, ima_bytes);
        total_compressed_bytes += ima_bytes;
        dec_frames = ima_adpcm_decode(ima_dec_state, post_amp, ima_data, ima_bytes);
        total_post_samples += dec_frames;
        for (i = 0;  i < frames;  i++)
        {
            history[hist_in++] = pre_amp[i];
            if (hist_in >= HIST_LEN)
                hist_in = 0;
            pre_energy += (double) pre_amp[i] * (double) pre_amp[i];
        }
        for (i = 0;  i < dec_frames;  i++)
        {
            post_energy += (double) post_amp[i] * (double) post_amp[i];
            xx = post_amp[i] - history[hist_out++];
            if (hist_out >= HIST_LEN)
                hist_out = 0;
            diff_energy += (double) xx * (double) xx;
        }
        outframes = sf_writef_short(outhandle, post_amp, dec_frames);
    }
    if (sf_close_telephony(inhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", in_file_name);
        exit(2);
    }
    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    ima_adpcm_release(ima_enc_state);
    ima_adpcm_release(ima_dec_state);

    printf("Pre samples: %d\n", total_pre_samples);
    printf("Compressed bytes: %d\n", total_compressed_bytes);
    printf("Post samples: %d\n", total_post_samples);

    printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy);
    printf("Residual energy is %f%% of the total.\n", 100.0*diff_energy/post_energy);
    if (fabs(1.0 - post_energy/pre_energy) > 0.05
        ||
        fabs(diff_energy/post_energy) > 0.03)
    {
        printf("Tests failed.\n");
        exit(2);
    }
    
    printf("Tests passed.\n");
    return 0;
}
static int end_to_end_tests(void)
{
    ademco_contactid_receiver_state_t *receiver;
    ademco_contactid_sender_state_t *sender;
    logging_state_t *logging;
    codec_munge_state_t *munge;
    awgn_state_t noise_source;
    int16_t amp[SAMPLES_PER_CHUNK];
    int16_t sndfile_buf[2*SAMPLES_PER_CHUNK];
    int samples;
    int i;
    int j;

    printf("End to end tests\n");

    if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL)
    {
        fprintf(stderr, "    Cannot open audio file '%s'\n", OUTPUT_FILE_NAME);
        exit(2);
    }

    if ((receiver = ademco_contactid_receiver_init(NULL, rx_callback, NULL)) == NULL)
        return -1;
    ademco_contactid_receiver_set_realtime_callback(receiver, rx_callback, receiver);

    logging = ademco_contactid_receiver_get_logging_state(receiver);
    span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
    span_log_set_tag(logging, "Ademco-rx");

    if ((sender = ademco_contactid_sender_init(NULL, tx_callback, NULL)) == NULL)
        return -1;
    ademco_contactid_sender_set_realtime_callback(sender, tx_callback, sender);
    logging = ademco_contactid_sender_get_logging_state(sender);
    span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
    span_log_set_tag(logging, "Ademco-tx");

    awgn_init_dbm0(&noise_source, 1234567, -50);
    munge = codec_munge_init(MUNGE_CODEC_ALAW, 0);

    sending_complete = FALSE;
    rx_callback_reported = FALSE;

    for (i = 0;  i < 1000;  i++)
    {
        samples = ademco_contactid_sender_tx(sender, amp, SAMPLES_PER_CHUNK);
        for (j = samples;  j < SAMPLES_PER_CHUNK;  j++)
            amp[j] = 0;
        for (j = 0;  j < SAMPLES_PER_CHUNK;  j++)
            sndfile_buf[2*j] = amp[j];
        /* There is no point in impairing this signal. It is just DTMF tones, which
           will work as wel as the DTMF detector beign used. */
        ademco_contactid_receiver_rx(receiver, amp, SAMPLES_PER_CHUNK);

        samples = ademco_contactid_receiver_tx(receiver, amp, SAMPLES_PER_CHUNK);
        for (j = samples;  j < SAMPLES_PER_CHUNK;  j++)
            amp[j] = 0;
        
        /* We add AWGN and codec impairments to the signal, to stress the tone detector. */
        codec_munge(munge, amp, SAMPLES_PER_CHUNK);
        for (j = 0;  j < SAMPLES_PER_CHUNK;  j++)
        {
            sndfile_buf[2*j + 1] = amp[j];
            /* Add noise to the tones */
            amp[j] += awgn(&noise_source);
        }
        codec_munge(munge, amp, SAMPLES_PER_CHUNK);
        ademco_contactid_sender_rx(sender, amp, SAMPLES_PER_CHUNK);

        sf_writef_short(outhandle, sndfile_buf, SAMPLES_PER_CHUNK);
    }
    if (!rx_callback_reported)
    {
        fprintf(stderr, "    Report not received\n");
        return -1;
    }

    if (sf_close_telephony(outhandle))
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
        return -1;
    }
    printf("    Passed\n");
    return 0;
}
Beispiel #29
0
int main(int argc, char *argv[])
{
    int i;
    SNDFILE *inhandle;
    SNDFILE *outhandle;
    int frames;
    int dec_frames;
    int outframes;
    int oki_bytes;
    int bit_rate;
    double pre_energy;
    double post_energy;
    double diff_energy;
    int16_t pre_amp[HIST_LEN];
    int16_t post_amp[HIST_LEN];
    uint8_t oki_data[HIST_LEN];
    int16_t history[HIST_LEN];
    int hist_in;
    int hist_out;
    oki_adpcm_state_t *oki_enc_state;
    oki_adpcm_state_t *oki_dec_state;
    oki_adpcm_state_t *oki_dec_state2;
    int xx;
    int total_pre_samples;
    int total_compressed_bytes;
    int total_post_samples;
    int successive_08_bytes;
    int successive_80_bytes;
    int encoded_fd;
    const char *encoded_file_name;
    const char *in_file_name;
    int log_encoded_data;
    int opt;

    bit_rate = 32000;
    encoded_file_name = NULL;
    in_file_name = IN_FILE_NAME;
    log_encoded_data = FALSE;
    while ((opt = getopt(argc, argv, "2d:i:l")) != -1)
    {
        switch (opt)
        {
        case '2':
            bit_rate = 24000;
            break;
        case 'd':
            encoded_file_name = optarg;
            break;
        case 'i':
            in_file_name = optarg;
            break;
        case 'l':
            log_encoded_data = TRUE;
            break;
        default:
            //usage();
            exit(2);
            break;
        }
    }

    if (encoded_file_name)
    {
        if ((encoded_fd = open(encoded_file_name, O_RDONLY)) < 0)
        {
            fprintf(stderr, "    Cannot open encoded file '%s'\n", encoded_file_name);
            exit(2);
        }
    }
    else
    {
        if ((inhandle = sf_open_telephony_read(in_file_name, 1)) == NULL)
        {
            fprintf(stderr, "    Cannot open audio file '%s'\n", in_file_name);
            exit(2);
        }
        if ((oki_enc_state = oki_adpcm_init(NULL, bit_rate)) == NULL)
        {
            fprintf(stderr, "    Cannot create encoder\n");
            exit(2);
        }
    }

    if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 1)) == NULL)
    {
        fprintf(stderr, "    Cannot create audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }
    if ((oki_dec_state = oki_adpcm_init(NULL, bit_rate)) == NULL)
    {
        fprintf(stderr, "    Cannot create decoder\n");
        exit(2);
    }
    if ((oki_dec_state2 = oki_adpcm_init(NULL, bit_rate)) == NULL)
    {
        fprintf(stderr, "    Cannot create decoder\n");
        exit(2);
    }

    hist_in = 0;
    if (bit_rate == 32000)
        hist_out = 0;
    else
        hist_out = HIST_LEN - 27;
    memset(history, 0, sizeof(history));
    pre_energy = 0.0;
    post_energy = 0.0;
    diff_energy = 0.0;
    total_pre_samples = 0;
    total_compressed_bytes = 0;
    total_post_samples = 0;
    if (encoded_file_name)
    {
        /* Decode a file of OKI ADPCM code to a linear wave file */
        while ((oki_bytes = read(encoded_fd, oki_data, 80)) > 0)
        {
            total_compressed_bytes += oki_bytes;
            dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes);
            total_post_samples += dec_frames;
            for (i = 0;  i < dec_frames;  i++)
            {
                post_energy += (double) post_amp[i] * (double) post_amp[i];
                xx = post_amp[i] - history[hist_out++];
                if (hist_out >= HIST_LEN)
                    hist_out = 0;
                diff_energy += (double) xx * (double) xx;
            }
            outframes = sf_writef_short(outhandle, post_amp, dec_frames);
        }
        close(encoded_fd);
    }
    else
    {
        /* Perform a linear wave file -> OKI ADPCM -> linear wave file cycle. Along the way
           check the decoder resets on the sequence specified for this codec, and the gain
           and worst case sample distortion. */
        successive_08_bytes = 0;
        successive_80_bytes = 0;
        while ((frames = sf_readf_short(inhandle, pre_amp, 159)))
        {
            total_pre_samples += frames;
            oki_bytes = oki_adpcm_encode(oki_enc_state, oki_data, pre_amp, frames);
            if (log_encoded_data)
                write(1, oki_data, oki_bytes);
            total_compressed_bytes += oki_bytes;
            /* Look for a condition which is defined as something which should cause a reset of
               the decoder (48 samples of 0, 8, 0, 8, etc.), and verify that it really does. Use
               a second decode, which we feed byte by byte, for this. */
            for (i = 0;  i < oki_bytes;  i++)
            {
                oki_adpcm_decode(oki_dec_state2, post_amp, &oki_data[i], 1);
                if (oki_data[i] == 0x08)
                    successive_08_bytes++;
                else
                    successive_08_bytes = 0;
                if (oki_data[i] == 0x80)
                    successive_80_bytes++;
                else
                    successive_80_bytes = 0;
                if (successive_08_bytes == 24  ||  successive_80_bytes == 24)
                {
                    if (oki_dec_state2->step_index != 0)
                    {
                        fprintf(stderr, "Decoder reset failure\n");
                        exit(2);
                    }
                }
            }
            dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes);
            total_post_samples += dec_frames;
            for (i = 0;  i < frames;  i++)
            {
                history[hist_in++] = pre_amp[i];
                if (hist_in >= HIST_LEN)
                    hist_in = 0;
                pre_energy += (double) pre_amp[i] * (double) pre_amp[i];
            }
            for (i = 0;  i < dec_frames;  i++)
            {
                post_energy += (double) post_amp[i] * (double) post_amp[i];
                xx = post_amp[i] - history[hist_out++];
                if (hist_out >= HIST_LEN)
                    hist_out = 0;
                diff_energy += (double) xx * (double) xx;
                //post_amp[i] = xx;
            }
            outframes = sf_writef_short(outhandle, post_amp, dec_frames);
        }
        printf("Pre samples: %d\n", total_pre_samples);
        printf("Compressed bytes: %d\n", total_compressed_bytes);
        printf("Post samples: %d\n", total_post_samples);

        printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy);
        printf("Residual energy is %f%% of the total.\n", 100.0*diff_energy/post_energy);
        if (bit_rate == 32000)
        {
            if (fabs(1.0 - post_energy/pre_energy) > 0.01
                ||
                fabs(diff_energy/post_energy) > 0.01)
            {
                printf("Tests failed.\n");
                exit(2);
            }
        }
        else
        {
            if (fabs(1.0 - post_energy/pre_energy) > 0.11
                ||
                fabs(diff_energy/post_energy) > 0.05)
            {
                printf("Tests failed.\n");
                exit(2);
            }
        }


        oki_adpcm_release(oki_enc_state);
        if (sf_close(inhandle) != 0)
        {
            fprintf(stderr, "    Cannot close audio file '%s'\n", in_file_name);
            exit(2);
        }
    }
    oki_adpcm_release(oki_dec_state);
    oki_adpcm_release(oki_dec_state2);
    if (sf_close(outhandle) != 0)
    {
        fprintf(stderr, "    Cannot close audio file '%s'\n", OUT_FILE_NAME);
        exit(2);
    }

    printf("Tests passed.\n");
    return 0;
}