Exemple #1
0
int main(int argc, char *argv[])
{
    int duration;
    int i;
    int j;
    int len;
    int sample;
    const char *s;
    char digit[2];
    char buf[MAX_BELL_MF_DIGITS + 1];
    int actual;
    int nplus;
    int nminus;
    float rrb;
    float rcfo;
    time_t now;
    bell_mf_rx_state_t *mf_state;
    awgn_state_t noise_source;

    time(&now);
    mf_state = bell_mf_rx_init(NULL, NULL, NULL);

    /* Test 1: Mitel's test 1 isn't really a test. Its a calibration step,
       which has no meaning here. */
    printf("Test 1: Calibration\n");
    printf("    Passed\n");

    /* Test 2: Decode check
       This is a sanity check, that all digits are reliably detected
       under ideal conditions.  Each possible digit is repeated 10 times,
       with 68ms bursts. The level of each tone is about 6dB down from clip */
    printf("Test 2: Decode check\n");
    my_mf_gen_init(0.0, -3, 0.0, -3, 68, 68);
    s = ALL_POSSIBLE_DIGITS;
    digit[1] = '\0';
    while (*s)
    {
        digit[0] = *s++;
        for (i = 0;  i < 10;  i++)
        {
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            actual = bell_mf_rx_get(mf_state, buf, 128);
            if (actual != 1  ||  buf[0] != digit[0])
            {
                printf("    Sent     '%s'\n", digit);
                printf("    Received '%s' [%d]\n", buf, actual);
                printf("    Failed\n");
                exit(2);
            }
        }
    }
    printf("    Passed\n");

    /* Test 3: Recognition bandwidth and channel centre frequency check.
       Use all digits. Each digit types requires four tests to complete
       the check. Each section contains 40 pulses of 68ms duration,
       with an amplitude of -20dB from clip per frequency.

       Four sections covering the tests for one tone (1 digit) are:
       a. H frequency at 0% deviation from center, L frequency at +0.1%.
          L frequency is then increments in +01.% steps up to +4%. The
          number of tone bursts is noted and designated N+.
       b. H frequency at 0% deviation, L frequency at -0.1%. L frequency
          is then incremental in -0.1% steps, up to -4%. The number of
          tone bursts is noted and designated N-.
       c. The test in (a) is repeated with the L frequency at 0% and the
          H frequency varied up to +4%.
       d. The test in (b) is repeated with the L frequency and 0% and the
          H frequency varied to -4%.

       Receiver Recognition Bandwidth (RRB) is calculated as follows:
            RRB% = (N+ + N-)/10
       Receiver Center Frequency Offset (RCFO) is calculated as follows:
            RCFO% = X + (N+ - N-)/20

       Note that this test doesn't test what it says it is testing at all,
       and the results are quite inaccurate, if not a downright lie! However,
       it follows the Mitel procedure, so how can it be bad? :)

       The spec calls for +-1.5% +-10Hz of bandwidth.
    */
    printf("Test 3: Recognition bandwidth and channel centre frequency check\n");
    s = ALL_POSSIBLE_DIGITS;
    digit[1] = '\0';
    j = 0;
    while (*s)
    {
        digit[0] = *s++;
        for (nplus = 0, i = 1;  i <= 60;  i++)
        {
            my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, 68);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nplus += bell_mf_rx_get(mf_state, buf, 128);
        }
        for (nminus = 0, i = -1;  i >= -60;  i--)
        {
            my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, 68);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nminus += bell_mf_rx_get(mf_state, buf, 128);
        }
        rrb = (float) (nplus + nminus)/10.0;
        rcfo = (float) (nplus - nminus)/10.0;
        printf("    %c (low)  rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n",
               digit[0],
               rrb,
               rcfo,
               (float) nminus/10.0,
               (float) nplus/10.0);

        if (rrb < 3.0 + rcfo + (2.0*100.0*10.0/bell_mf_tones[j].f1)  ||  rrb >= 15.0 + rcfo)
        {
            printf("    Failed\n");
            exit(2);
        }

        for (nplus = 0, i = 1;  i <= 60;  i++)
        {
            my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, 68);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nplus += bell_mf_rx_get(mf_state, buf, 128);
        }
        for (nminus = 0, i = -1;  i >= -60;  i--)
        {
            my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, 68);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nminus += bell_mf_rx_get(mf_state, buf, 128);
        }
        rrb = (float) (nplus + nminus)/10.0;
        rcfo = (float) (nplus - nminus)/10.0;
        printf("    %c (high) rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n",
               digit[0],
               rrb,
               rcfo,
               (float) nminus/10.0,
               (float) nplus/10.0);
        if (rrb < 3.0 + rcfo + (2.0*100.0*10.0/bell_mf_tones[j].f2)  ||  rrb >= 15.0 + rcfo)
        {
            printf("    Failed\n");
            exit(2);
        }
        j++;
    }
    printf("    Passed\n");

    /* Test 4: Acceptable amplitude ratio (twist).
       Twist all digits in both directions, and check the maximum twist
       we can accept. The way this is done is styled after the Mitel DTMF
       test, and has good and bad points. */

    printf("Test 4: Acceptable amplitude ratio (twist)\n");
    s = ALL_POSSIBLE_DIGITS;
    digit[1] = '\0';
    while (*s)
    {
        digit[0] = *s++;
        for (nplus = 0, i = -50;  i >= -250;  i--)
        {
            my_mf_gen_init(0.0, -5, 0.0, i/10, 68, 68);

            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nplus += bell_mf_rx_get(mf_state, buf, 128);
        }
        printf("    %c normal twist  = %.2fdB\n", digit[0], (float) nplus/10.0);
        if (nplus < 60)
        {
            printf("    Failed\n");
            exit(2);
        }
        for (nminus = 0, i = -50;  i >= -250;  i--)
        {
            my_mf_gen_init(0.0, i/10, 0.0, -5, 68, 68);

            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            nminus += bell_mf_rx_get(mf_state, buf, 128);
        }
        printf("    %c reverse twist = %.2fdB\n", digit[0], (float) nminus/10.0);
        if (nminus < 60)
        {
            printf("    Failed\n");
            exit(2);
        }
    }
    printf("    Passed\n");

    /* Test 5: Dynamic range
       This test sends all possible digits, with gradually increasing
       amplitude. We determine the span over which we achieve reliable
       detection. The spec says we should detect between -14dBm and 0dBm,
       but the tones clip above -3dBm, so this cannot really work. */

    printf("Test 5: Dynamic range\n");
    for (nplus = nminus = -1000, i = -50;  i <= 3;  i++)
    {
        my_mf_gen_init(0.0, i, 0.0, i, 68, 68);
        for (j = 0;  j < 100;  j++)
        {
            len = my_mf_generate(amp, ALL_POSSIBLE_DIGITS);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            if (bell_mf_rx_get(mf_state, buf, 128) != 15)
                break;
            if (strcmp(buf, ALL_POSSIBLE_DIGITS) != 0)
                break;
        }
        if (j == 100)
        {
            if (nplus == -1000)
                nplus = i;
        }
        else
        {
            if (nplus != -1000  &&  nminus == -1000)
                nminus = i;
        }
    }
    printf("    Dynamic range = %ddB to %ddB\n", nplus, nminus - 1);
    if (nplus > -22  ||  nminus <= -3)
    {
        printf("    Failed\n");
        exit(2);
    }
    printf("    Passed\n");

    /* Test 6: Guard time
       This test sends all possible digits, with a gradually reducing
       duration. The spec defines a narrow range of tone duration
       times we can expect, so as long as we detect reliably at the
       specified minimum we should be OK. However, the spec also says
       we should detect on a minimum of 55ms of KP, or 30ms of other
       digits. */

    printf("Test 6: Guard time\n");
    for (i = 30;  i < 62;  i++)
    {
        my_mf_gen_init(0.0, -5, 0.0, -3, i, 68);
        for (j = 0;  j < 500;  j++)
        {
            len = my_mf_generate(amp, ALL_POSSIBLE_DIGITS);
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            if (bell_mf_rx_get(mf_state, buf, 128) != 15)
                break;
            if (strcmp(buf, ALL_POSSIBLE_DIGITS) != 0)
                break;
        }
        if (j == 500)
            break;
    }
    printf("    Guard time = %dms\n", i);
    if (i > 61)
    {
        printf("    Failed\n");
        exit(2);
    }
    printf("    Passed\n");

    /* Test 7: Acceptable signal to noise ratio
       We send all possible digits at -6dBm from clip, mixed with AWGN.
       We gradually reduce the noise until we get clean detection. */

    printf("Test 7: Acceptable signal to noise ratio\n");
    my_mf_gen_init(0.0, -3, 0.0, -3, 68, 68);
    for (i = -10;  i > -50;  i--)
    {
        awgn_init_dbm0(&noise_source, 1234567, (float) i);
        for (j = 0;  j < 500;  j++)
        {
            len = my_mf_generate(amp, ALL_POSSIBLE_DIGITS);
            for (sample = 0;  sample < len;  sample++)
                amp[sample] = saturate(amp[sample] + awgn(&noise_source));
            codec_munge(amp, len);
            bell_mf_rx(mf_state, amp, len);
            if (bell_mf_rx_get(mf_state, buf, 128) != 15)
                break;
            if (strcmp(buf, ALL_POSSIBLE_DIGITS) != 0)
                break;
        }
        if (j == 500)
            break;
    }
    printf("    Acceptable S/N ratio is %ddB\n", -3 - i);
    if (-3 - i > 26)
    {
        printf("    Failed\n");
        exit(2);
    }
    bell_mf_rx_free(mf_state);
    printf("    Passed\n");

    /* The remainder of the Mitel tape is the talk-off test. This is
       meaningless for Bell MF. However the decoder's tolerance of
       out of band noise is significant. */
    /* TODO: add a OOB tolerance test. */

    /* Test the callback mode for delivering detected digits */

    printf("Test: Callback digit delivery mode.\n");
    callback_ok = false;
    callback_roll = 0;
    mf_state = bell_mf_rx_init(NULL, digit_delivery, (void *) 0x12345678);
    my_mf_gen_init(0.0, -10, 0.0, -10, 68, 68);
    for (i = 1;  i < 10;  i++)
    {
        len = 0;
        for (j = 0;  j < i;  j++)
            len += my_mf_generate(amp + len, ALL_POSSIBLE_DIGITS);
        bell_mf_rx(mf_state, amp, len);
        if (!callback_ok)
            break;
    }
    if (!callback_ok)
    {
        printf("    Failed\n");
        exit(2);
    }
    bell_mf_rx_free(mf_state);
    printf("    Passed\n");

    duration = time (NULL) - now;
    printf("Tests passed in %ds\n", duration);
    return 0;
}
Exemple #2
0
static int test_a_tone_set(int fwd)
{
    int i;
    int j;
    int len;
    int sample;
    const char *s;
    char digit;
    int actual;
    int nplus;
    int nminus;
    float rrb;
    float rcfo;
    int16_t amp[100000];
    r2_mf_rx_state_t mf_state;
    awgn_state_t noise_source;
    const mf_digit_tones_t *tone;

    if (fwd)
        tone = &r2_mf_fwd_tones[0];
    else
        tone = &r2_mf_back_tones[0];
    r2_mf_rx_init(&mf_state, fwd);

    /* Test 1: Mitel's test 1 isn't really a test. Its a calibration step,
       which has no meaning here. */

    printf ("Test 1: Calibration\n");
    printf ("    Passed\n");

    /* Test 2: Decode check
       This is a sanity check, that all digits are reliably detected
       under ideal conditions.  Each possible digit is repeated 10 times,
       with 68ms bursts. The level of each tone is about 6dB down from clip */

    printf ("Test 2: Decode check\n");
    my_mf_gen_init(0.0, -3, 0.0, -3, 68, fwd);
    s = r2_mf_tone_codes;
    while (*s)
    {
        digit = *s++;
        for (i = 0;  i < 10;  i++)
        {
            len = my_mf_generate(amp, digit);
            codec_munge (amp, len);
            actual = r2_mf_rx(&mf_state, amp, len);
            if (actual != digit)
            {
                printf ("    Sent     '%c'\n", digit);
                printf ("    Received 0x%X\n", actual);
                printf ("    Failed\n");
                exit (2);
            }
        }
    }
    printf ("    Passed\n");

    /* Test 3: Recognition bandwidth and channel centre frequency check.
       Use all digits. Each digit types requires four tests to complete
       the check. Each section contains 40 pulses of 68ms duration,
       with an amplitude of -20dB from clip per frequency.

       Four sections covering the tests for one tone (1 digit) are:
       a. H frequency at 0% deviation from center, L frequency at +0.1%.
          L frequency is then increments in +01.% steps up to +4%. The
          number of tone bursts is noted and designated N+.
       b. H frequency at 0% deviation, L frequency at -0.1%. L frequency
          is then incremental in -0.1% steps, up to -4%. The number of
          tone bursts is noted and designated N-.
       c. The test in (a) is repeated with the L frequency at 0% and the
          H frequency varied up to +4%.
       d. The test in (b) is repeated with the L frequency and 0% and the
          H frequency varied to -4%.

       Receiver Recognition Bandwidth (RRB) is calculated as follows:
            RRB% = (N+ + N-)/10
       Receiver Center Frequency Offset (RCFO) is calculated as follows:
            RCFO% = X + (N+ - N-)/20
            
       Note that this test doesn't test what it says it is testing at all,
       and the results are quite inaccurate, if not a downright lie! However,
       it follows the Mitel procedure, so how can it be bad? :)
       
       The spec calls for +-4 +-10Hz (ie +-14Hz) of bandwidth. */

    printf ("Test 3: Recognition bandwidth and channel centre frequency check\n");
    s = r2_mf_tone_codes;
    j = 0;
    while (*s)
    {
        digit = *s++;
        for (nplus = 0, i = 1;  i <= 60;  i++)
        {
            my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, fwd);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nplus++;
        }
        for (nminus = 0, i = -1;  i >= -60;  i--)
        {
            my_mf_gen_init((float) i/1000.0, -17, 0.0, -17, 68, fwd);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nminus++;
        }
        rrb = (float) (nplus + nminus)/10.0;
        rcfo = (float) (nplus - nminus)/10.0;
        printf ("    %c (low)  rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n",
                digit,
                rrb,
                rcfo,
                (float) nminus/10.0,
                (float) nplus/10.0);

        if (rrb < rcfo + (2.0*100.0*14.0/r2_mf_fwd_tones[j].f1)  ||  rrb >= 15.0 + rcfo)
        {
            printf ("    Failed\n");
            exit (2);
        }

        for (nplus = 0, i = 1;  i <= 60;  i++)
        {
            my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, fwd);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nplus++;
        }
        for (nminus = 0, i = -1;  i >= -60;  i--)
        {
            my_mf_gen_init(0.0, -17, (float) i/1000.0, -17, 68, fwd);
            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nminus++;
        }
        rrb = (float) (nplus + nminus)/10.0;
        rcfo = (float) (nplus - nminus)/10.0;
        printf ("    %c (high) rrb = %5.2f%%, rcfo = %5.2f%%, max -ve = %5.2f, max +ve = %5.2f\n",
                digit,
                rrb,
                rcfo,
                (float) nminus/10.0,
                (float) nplus/10.0);
        if (rrb < rcfo + (2.0*100.0*14.0/r2_mf_fwd_tones[j].f2)  ||  rrb >= 15.0 + rcfo)
        {
            printf ("    Failed\n");
            exit (2);
        }
        j++;
    }
    printf ("    Passed\n");

    /* Test 4: Acceptable amplitude ratio (twist).
       Twist all digits in both directions, and check the maximum twist
       we can accept. The way this is done is styled after the Mitel DTMF
       test, and has good and bad points. */

    printf ("Test 4: Acceptable amplitude ratio (twist)\n");
    s = r2_mf_tone_codes;
    while (*s)
    {
        digit = *s++;
        for (nplus = 0, i = -50;  i >= -250;  i--)
        {
            my_mf_gen_init(0.0, -5, 0.0, i/10, 68, fwd);

            len = my_mf_generate(amp, digit);
            codec_munge (amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nplus++;
        }
        printf ("    %c normal twist  = %.2fdB\n", digit, (float) nplus/10.0);
        if (nplus < 70)
        {
            printf ("    Failed\n");
            exit (2);
        }
        for (nminus = 0, i = -50;  i >= -250;  i--)
        {
            my_mf_gen_init(0.0, i/10, 0.0, -5, 68, fwd);

            len = my_mf_generate(amp, digit);
            codec_munge(amp, len);
            if (r2_mf_rx(&mf_state, amp, len) == digit)
                nminus++;
        }
        printf ("    %c reverse twist = %.2fdB\n", digit, (float) nminus/10.0);
        if (nminus < 70)
        {
            printf ("    Failed\n");
            exit (2);
        }
    }
    printf ("    Passed\n");

    /* Test 5: Dynamic range
       This test sends all possible digits, with gradually increasing 
       amplitude. We determine the span over which we achieve reliable
       detection. */
       
    printf ("Test 5: Dynamic range\n");
    for (nplus = nminus = -1000, i = -50;  i <= 3;  i++)
    {
        s = r2_mf_tone_codes;
        while (*s)
        {
            digit = *s++;
            my_mf_gen_init(0.0, i, 0.0, i, 68, fwd);
            for (j = 0;  j < 100;  j++)
            {
                len = my_mf_generate(amp, digit);
                codec_munge(amp, len);
                if (r2_mf_rx(&mf_state, amp, len) != digit)
                    break;
            }
            if (j < 100)
                break;
        }
        if (j == 100)
        {
            if (nplus == -1000)
                nplus = i;
        }
        else
        {
            if (nplus != -1000  &&  nminus == -1000)
                nminus = i;
        }
    }
    printf ("    Dynamic range = %ddB to %ddB\n", nplus, nminus - 1);
    if (nplus > -35  ||  nminus <= -5)
    {
        printf("    Failed\n");
        exit(2);
    }
    printf ("    Passed\n");

    /* Test 6: Guard time
       This test sends all possible digits, with a gradually reducing 
       duration. */

    printf ("Test 6: Guard time\n");
    for (i = 30;  i < 62;  i++)
    {
        s = r2_mf_tone_codes;
        j = 0;
        while (*s)
        {
            digit = *s++;
            my_mf_gen_init(0.0, -5, 0.0, -3, i, fwd);
            for (j = 0;  j < 500;  j++)
            {
                len = my_mf_generate(amp, digit);
                codec_munge(amp, len);
                if (r2_mf_rx(&mf_state, amp, len) != digit)
                    break;
            }
            if (j < 500)
                break;
        }
        if (j == 500)
            break;
    }
    printf ("    Guard time = %dms\n", i);
    if (i > 61)
    {
        printf("    Failed\n");
        exit(2);
    }
    printf ("    Passed\n");

    /* Test 7: Acceptable signal to noise ratio
       We send all possible digits at -6dBm from clip, mixed with AWGN.
       We gradually reduce the noise until we get clean detection. */

    printf ("Test 7: Acceptable signal to noise ratio\n");
    my_mf_gen_init(0.0, -3, 0.0, -3, 68, fwd);
    for (i = -3;  i > -50;  i--)
    {
        s = r2_mf_tone_codes;
        while (*s)
        {
            digit = *s++;
            awgn_init_dbm0(&noise_source, 1234567, (float) i);
            for (j = 0;  j < 500;  j++)
            {
                len = my_mf_generate(amp, digit);
                for (sample = 0;  sample < len;  sample++)
                    amp[sample] = saturate(amp[sample] + awgn(&noise_source));
                codec_munge(amp, len);
                if (r2_mf_rx(&mf_state, amp, len) != digit)
                    break;
            }
            if (j < 500)
                break;
        }
        if (j == 500)
            break;
    }
    printf("    Acceptable S/N ratio is %ddB\n", -3 - i);
    if (-3 - i > 26)
    {
        printf("    Failed\n");
        exit(2);
    }
    printf("    Passed\n");

    /* The remainder of the Mitel tape is the talk-off test. This is
       meaningless for R2 MF. However the decoder's tolerance of
       out of band noise is significant. */
    /* TODO: add a OOB tolerance test. */
    
    return 0;
}