Exemple #1
0
void rmlt_coefs_to_samples(int16_t coefs[],
                           int16_t old_samples[],
                           int16_t out_samples[],
                           int dct_length,
                           int16_t mag_shift)
{
    int i;
    int half_dct_length;
    int last;
    int16_t new_samples[MAX_DCT_LENGTH];
    const int16_t *win;
    int32_t sum;

    half_dct_length = dct_length >> 1;

    /* Perform a Type IV (inverse) DCT on the coefficients */
    dct_type_iv_s(coefs, new_samples, dct_length);

    if (mag_shift > 0)
    {
        for (i = 0;  i < dct_length;  i++)
            new_samples[i] = shr(new_samples[i], mag_shift);
    }
    else if (mag_shift < 0)
    {
        mag_shift = negate(mag_shift);
        for (i = 0;  i < dct_length;  i++)
            new_samples[i] = shl(new_samples[i], mag_shift);
    }

    win = (dct_length == DCT_LENGTH)  ?  rmlt_to_samples_window  :  max_rmlt_to_samples_window;
    last = half_dct_length - 1;
    for (i = 0;  i < half_dct_length;  i++)
    {
        /* Get the first half of the windowed samples */
        sum = L_mult(win[i], new_samples[last - i]);
        sum = L_mac(sum, win[dct_length - i - 1], old_samples[i]);
        out_samples[i] = xround(L_shl(sum, 2));
        /* Get the second half of the windowed samples */
        sum = L_mult(win[half_dct_length + i], new_samples[i]);
        sum = L_mac(sum, negate(win[last - i]), old_samples[last - i]);
        out_samples[half_dct_length + i] = xround(L_shl(sum, 2));
    }

    /* Save the second half of the new samples for
       next time, when they will be the old samples. */
    vec_copyi16(old_samples, &new_samples[half_dct_length], half_dct_length);
}
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;
}
Exemple #3
0
int16_t samples_to_rmlt_coefs(const int16_t new_samples[],
                              int16_t old_samples[],
                              int16_t coefs[],
                              int dct_length)
{
    int i;
    int half_dct_length;
    int last;
    int16_t mag_shift;
    int16_t n;
    int16_t windowed_data[MAX_DCT_LENGTH];
    const int16_t *win;
    int32_t acca;
    int32_t accb;
    int16_t temp;
    int16_t temp1;
    int16_t temp2;

    half_dct_length = dct_length >> 1;

    win = (dct_length == DCT_LENGTH)  ?  samples_to_rmlt_window  :  max_samples_to_rmlt_window;
    /* Get the first half of the windowed samples */
    last = half_dct_length - 1;
    for (i = 0;  i < half_dct_length;  i++)
    {
        acca = L_mult(win[last - i], old_samples[last - i]);
        acca = L_mac(acca, win[half_dct_length + i], old_samples[half_dct_length + i]);
        windowed_data[i] = xround(acca);
    }
    /* Get the second half of the windowed samples */
    last = dct_length - 1;
    for (i = 0;  i < half_dct_length;  i++)
    {
        acca = L_mult(win[last - i], new_samples[i]);
        acca = L_mac(acca, negate(win[i]), new_samples[last - i]);
        windowed_data[half_dct_length + i] = xround(acca);
    }

    /* Save the new samples for next time, when they will be the old samples. */
    vec_copyi16(old_samples, new_samples, dct_length);

    /* Calculate how many bits to shift up the input to the DCT. */
    temp1 = 0;
    for (i = 0;  i < dct_length;  i++)
    {
        temp2 = abs_s(windowed_data[i]);
        temp = sub(temp2, temp1);
        if (temp > 0)
            temp1 = temp2;
    }

    mag_shift = 0;
    temp = sub(temp1, 14000);
    if (temp < 0)
    {
        temp = sub(temp1, 438);
        temp = (temp < 0)  ?  add(temp1, 1)  :  temp1;
        accb = L_mult(temp, 9587);
        acca = L_shr(accb, 20);
        temp = norm_s((int16_t) acca);
        mag_shift = (temp == 0)  ?  9  :  sub(temp, 6);
    }

    acca = 0;
    for (i = 0;  i < dct_length;  i++)
    {
        temp = abs_s(windowed_data[i]);
        acca = L_add(acca, temp);
    }

    acca = L_shr(acca, 7);
    if (temp1 < acca)
        mag_shift = sub(mag_shift, 1);
    if (mag_shift > 0)
    {
        for (i = 0;  i < dct_length;  i++)
            windowed_data[i] = shl(windowed_data[i], mag_shift);
    }
    else if (mag_shift < 0)
    {
        n = negate(mag_shift);
        for (i = 0;  i < dct_length;  i++)
            windowed_data[i] = shr(windowed_data[i], n);
    }

    /* Perform a Type IV DCT on the windowed data to get the coefficients */
    dct_type_iv_a(windowed_data, coefs, dct_length);

    return mag_shift;
}