Esempio n. 1
0
// 
// AUTOTEST: identity
//
void autotest_matrixcf_eye() {
    float complex x[16]= {
      9+  4*_I,   4+  9*_I,   5+  4*_I,   4+  5*_I, 
      3+  9*_I,   9+  2*_I,   9+  7*_I,   9+  2*_I, 
      9+  4*_I,   1+  9*_I,   8+  6*_I,   0+  2*_I, 
      4+  9*_I,   3+  6*_I,   3+  3*_I,   7+  8*_I
    };

    float complex I4_test[16] = {
        1,  0,  0,  0,
        0,  1,  0,  0,
        0,  0,  1,  0,
        0,  0,  0,  1};

    float complex y[16];
    float complex z[16];

    // generate identity matrix
    matrixcf_eye(y,4);
    CONTEND_SAME_DATA(y, I4_test, 16*sizeof(float complex));

    // multiply with input
    matrixcf_mul(x, 4, 4,
                 y, 4, 4,
                 z, 4, 4);
    CONTEND_SAME_DATA(x, z, 16*sizeof(float complex));
}
Esempio n. 2
0
//
// AUTOTEST: wdelayf
//
void autotest_wdelayf()
{
    float v;    // reader
    unsigned int i;

    // create wdelay
    // wdelay: 0 0 0 0
    wdelayf w = wdelayf_create(4);

    wdelayf_read(w, &v);
    CONTEND_EQUALITY(v, 0);

    float x0[10]      = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    float y0_test[10] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6};
    float y0[10];

    for (i=0; i<10; i++) {
        wdelayf_read(w, &y0[i]);
        wdelayf_push(w,  x0[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y0[i], y0_test[i]);
    }
    // 7 8 9 10
    CONTEND_SAME_DATA(y0, y0_test, 10*sizeof(float));

    // re-create wdelay object
    // wdelay: 0 0 7 8 9 10
    w = wdelayf_recreate(w,6);

    float x1[10]     = {3, 4, 5, 6, 7, 8, 9, 2, 2, 2};
    float y1_test[10]= {0, 0, 7, 8, 9, 10,3, 4, 5, 6};
    float y1[10];
    for (i=0; i<10; i++) {
        wdelayf_read(w, &y1[i]);
        wdelayf_push(w,  x1[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y1[i], y1_test[i]);
    }
    // wdelay: 7 8 9 2 2 2
    CONTEND_SAME_DATA(y1, y1_test, 10*sizeof(float));

    // re-create wdelay object
    // wdelay: 8 9 2 2 2
    w = wdelayf_recreate(w,5);

    float x2[10]     = {1, 1, 1, 1, 1, 1, 1, 2, 3, 4};
    float y2_test[10]= {8, 9, 2, 2, 2, 1, 1, 1, 1, 1};
    float y2[10];

    for (i=0; i<10; i++) {
        wdelayf_read(w, &y2[i]);
        wdelayf_push(w,  x2[i]);
        //printf("%3u : %6.2f (%6.2f)\n", i, y1[i], y1_test[i]);
    }
    // wdelay: 1 1 2 3 4
    CONTEND_SAME_DATA(y2, y2_test, 10*sizeof(float));

    // destroy object
    wdelayf_destroy(w);
}
Esempio n. 3
0
void autotest_fft_shift_8()
{
    float complex x[] = {
        0 + 0*_Complex_I,
        1 + 1*_Complex_I,
        2 + 2*_Complex_I,
        3 + 3*_Complex_I,
        4 + 4*_Complex_I,
        5 + 5*_Complex_I,
        6 + 6*_Complex_I,
        7 + 7*_Complex_I
    };

    float complex test[] = {
        4 + 4*_Complex_I,
        5 + 5*_Complex_I,
        6 + 6*_Complex_I,
        7 + 7*_Complex_I,
        0 + 0*_Complex_I,
        1 + 1*_Complex_I,
        2 + 2*_Complex_I,
        3 + 3*_Complex_I
    };

    fft_shift(x,8);

    CONTEND_SAME_DATA(x,test,8*sizeof(float complex));
}
Esempio n. 4
0
// 
// AUTOTEST: Test matrixcf ops
//
void autotest_matrixcf_mul() {

    float complex x[6] = {
      9+  9*_I,   3+  4*_I,   8+  3*_I, 
      0+  3*_I,   6+ 10*_I,   6+  1*_I
    };

    float complex y[9] = {
      8+  7*_I,   4+  9*_I,   4+  1*_I, 
      5+  6*_I,  10+  2*_I,   6+  3*_I, 
      6+  9*_I,   2+  8*_I,   5+  5*_I
    };

    float complex z[6];
    float complex ztest[6] = {
     21+263*_I, -31+233*_I,  58+133*_I, 
    -24+170*_I,  17+174*_I,  28+125*_I
    };
    
    matrixcf_mul(x,2,3, y,3,3, z,2,3);
    if (liquid_autotest_verbose)
        matrixcf_print(z,2,3);

    CONTEND_SAME_DATA(z,ztest,sizeof(z));
}
Esempio n. 5
0
// test unscrambling of soft bits (helper function to keep code base small)
void liquid_scramble_soft_test(unsigned int _n)
{
    unsigned char msg_org[_n];      // input data
    unsigned char msg_enc[_n];      // scrambled data 
    unsigned char msg_soft[8*_n];   // scrambled data (soft bits)
    unsigned char msg_dec[_n];      // unscrambled data

    unsigned int i;

    // initialize data array (random)
    for (i=0; i<_n; i++)
        msg_org[i] = rand() & 0xff;

    // scramble input
    memmove(msg_enc, msg_org, _n);
    scramble_data(msg_enc,_n);

    // convert to soft bits
    for (i=0; i<_n; i++)
        liquid_unpack_soft_bits(msg_enc[i], 8, &msg_soft[8*i]);

    // unscramble result
    unscramble_data_soft(msg_soft, _n);

    // unpack soft bits
    for (i=0; i<_n; i++) {
        unsigned int sym_out;
        liquid_pack_soft_bits(&msg_soft[8*i], 8, &sym_out);
        msg_dec[i] = sym_out;
    }

    // ensure data are equivalent
    CONTEND_SAME_DATA(msg_org, msg_dec, _n);
}
Esempio n. 6
0
// helper function to keep code base small
void liquid_scramble_test(unsigned int _n)
{
    unsigned char x[_n];    // input data
    unsigned char y[_n];    // scrambled data
    unsigned char z[_n];    // unscrambled data

    unsigned int i;

    // initialize data array
    for (i=0; i<_n; i++)
        x[i] = 0x00;

    // scramble input
    memmove(y,x,_n);
    scramble_data(y,_n);

    // unscramble result
    memmove(z,y,_n);
    unscramble_data(z,_n);

    // ensure data are equivalent
    CONTEND_SAME_DATA(x,z,_n*sizeof(unsigned char));

    // compute entropy metric
    float H = liquid_scramble_test_entropy(y,_n);
    CONTEND_EXPRESSION( H > 0.8f );
}
Esempio n. 7
0
// Helper function to keep code base small
void fec_test_codec(fec_scheme _fs, unsigned int _n, void * _opts)
{
#if !LIBFEC_ENABLED
    if ( _fs == LIQUID_FEC_CONV_V27    ||
         _fs == LIQUID_FEC_CONV_V29    ||
         _fs == LIQUID_FEC_CONV_V39    ||
         _fs == LIQUID_FEC_CONV_V615   ||
         _fs == LIQUID_FEC_CONV_V27P23 ||
         _fs == LIQUID_FEC_CONV_V27P34 ||
         _fs == LIQUID_FEC_CONV_V27P45 ||
         _fs == LIQUID_FEC_CONV_V27P56 ||
         _fs == LIQUID_FEC_CONV_V27P67 ||
         _fs == LIQUID_FEC_CONV_V27P78 ||
         _fs == LIQUID_FEC_CONV_V29P23 ||
         _fs == LIQUID_FEC_CONV_V29P34 ||
         _fs == LIQUID_FEC_CONV_V29P45 ||
         _fs == LIQUID_FEC_CONV_V29P56 ||
         _fs == LIQUID_FEC_CONV_V29P67 ||
         _fs == LIQUID_FEC_CONV_V29P78 ||
         _fs == LIQUID_FEC_RS_M8)
    {
        AUTOTEST_WARN("convolutional, Reed-Solomon codes unavailable (install libfec)\n");
        return;
    }
#endif

    // generate fec object
    fec q = fec_create(_fs,_opts);

    // create arrays
    unsigned int n_enc = fec_get_enc_msg_length(_fs,_n);
    unsigned char msg[_n];          // original message
    unsigned char msg_enc[n_enc];   // encoded message
    unsigned char msg_dec[_n];      // decoded message

    // initialze message
    unsigned int i;
    for (i=0; i<_n; i++) {
        msg[i] = rand() & 0xff;
        msg_dec[i] = 0;
    }

    // encode message
    fec_encode(q,_n,msg,msg_enc);

    // channel: add single error
    msg_enc[0] ^= 0x01;

    // decode message
    fec_decode(q,_n,msg_enc,msg_dec);

    // validate output
    CONTEND_SAME_DATA(msg,msg_dec,_n);

    // clean up objects
    fec_destroy(q);
}
Esempio n. 8
0
//
// AUTOTEST: repeat/3 codec
//
void autotest_rep5_codec()
{
    unsigned int n=4;
    unsigned char msg[] = {0x25, 0x62, 0x3F, 0x52};
    fec_scheme fs = LIQUID_FEC_REP5;

    // create arrays
    unsigned int n_enc = fec_get_enc_msg_length(fs,n);
    unsigned char msg_dec[n];
    unsigned char msg_enc[n_enc];

    // create object
    fec q = fec_create(fs,NULL);
    if (liquid_autotest_verbose)
        fec_print(q);

    // encode message
    fec_encode(q, n, msg, msg_enc);
    
    // corrupt encoded message, but no so much that it
    // can't be decoded
    msg_enc[ 0] = ~msg_enc[ 0];
    msg_enc[ 4] = ~msg_enc[ 4];
//  msg_enc[ 8] = ~msg_enc[ 8];
//  msg_enc[12] = ~msg_enc[12];
//  msg_enc[16] = ~msg_enc[16];

    msg_enc[ 1] = ~msg_enc[ 1];
//  msg_enc[ 5] = ~msg_enc[ 5];
    msg_enc[ 9] = ~msg_enc[ 9];
//  msg_enc[13] = ~msg_enc[13];
//  msg_enc[17] = ~msg_enc[17];

//  msg_enc[ 2] = ~msg_enc[ 2];
//  msg_enc[ 6] = ~msg_enc[ 6];
    msg_enc[10] = ~msg_enc[10];
    msg_enc[14] = ~msg_enc[14];
//  msg_enc[18] = ~msg_enc[18];

    msg_enc[ 3] = ~msg_enc[ 3];
//  msg_enc[ 7] = ~msg_enc[ 7];
//  msg_enc[11] = ~msg_enc[11];
//  msg_enc[15] = ~msg_enc[15];
    msg_enc[19] = ~msg_enc[19];

    // decode message
    fec_decode(q, n, msg_enc, msg_dec);

    // validate data are the same
    CONTEND_SAME_DATA(msg, msg_dec, n);

    // clean up objects
    fec_destroy(q);
}
Esempio n. 9
0
//
// AUTOTEST : rbshift
//
void autotest_rbshift() {
    // input        : 1000 0001 1110 1111 0101 1111 1010 1010
    // output [0]   : 1000 0001 1110 1111 0101 1111 1010 1010
    // output [1]   : 0100 0000 1111 0111 1010 1111 1101 0101
    // output [2]   : 0010 0000 0111 1011 1101 0111 1110 1010
    // output [3]   : 0001 0000 0011 1101 1110 1011 1111 0101
    // output [4]   : 0000 1000 0001 1110 1111 0101 1111 1010
    // output [5]   : 0000 0100 0000 1111 0111 1010 1111 1101
    // output [6]   : 0000 0010 0000 0111 1011 1101 0111 1110
    // output [7]   : 0000 0001 0000 0011 1101 1110 1011 1111
    unsigned char input[4] = {0x81, 0xEF, 0x5F, 0xAA};
    
    unsigned char output_test_0[4] = {0x81, 0xEF, 0x5F, 0xAA};
    unsigned char output_test_1[4] = {0x40, 0xF7, 0xAF, 0xD5};
    unsigned char output_test_2[4] = {0x20, 0x7B, 0xD7, 0xEA};
    unsigned char output_test_3[4] = {0x10, 0x3D, 0xEB, 0xF5};
    unsigned char output_test_4[4] = {0x08, 0x1E, 0xF5, 0xFA};
    unsigned char output_test_5[4] = {0x04, 0x0F, 0x7A, 0xFD};
    unsigned char output_test_6[4] = {0x02, 0x07, 0xBD, 0x7E};
    unsigned char output_test_7[4] = {0x01, 0x03, 0xDE, 0xBF};

    unsigned char output[4];
    
    // 
    // run tests
    //
    unsigned int i;
    for (i=0; i<8; i++) {
        memmove(output, input, 4);
        liquid_rbshift( output, 4, i);
        switch (i) {
        case 0: CONTEND_SAME_DATA( output, output_test_0, 4 ); break;
        case 1: CONTEND_SAME_DATA( output, output_test_1, 4 ); break;
        case 2: CONTEND_SAME_DATA( output, output_test_2, 4 ); break;
        case 3: CONTEND_SAME_DATA( output, output_test_3, 4 ); break;
        case 4: CONTEND_SAME_DATA( output, output_test_4, 4 ); break;
        case 5: CONTEND_SAME_DATA( output, output_test_5, 4 ); break;
        case 6: CONTEND_SAME_DATA( output, output_test_6, 4 ); break;
        case 7: CONTEND_SAME_DATA( output, output_test_7, 4 ); break;
        default:;
        }
    }
}
Esempio n. 10
0
//
// AUTOTEST : lbcircshift
//
void autotest_lbcircshift() {
    // input        : 1001 0001 1110 1111 0101 1111 1010 1010
    // output [0]   : 1001 0001 1110 1111 0101 1111 1010 1010
    // output [1]   : 0010 0011 1101 1110 1011 1111 0101 0101
    // output [2]   : 0100 0111 1011 1101 0111 1110 1010 1010
    // output [3]   : 1000 1111 0111 1010 1111 1101 0101 0100
    // output [4]   : 0001 1110 1111 0101 1111 1010 1010 1001
    // output [5]   : 0011 1101 1110 1011 1111 0101 0101 0010
    // output [6]   : 0111 1011 1101 0111 1110 1010 1010 0100
    // output [7]   : 1111 0111 1010 1111 1101 0101 0100 1000
    unsigned char input[4] = {0x91, 0xEF, 0x5F, 0xAA};
    
    unsigned char output_test_0[4] = {0x91, 0xEF, 0x5F, 0xAA};
    unsigned char output_test_1[4] = {0x23, 0xDE, 0xBF, 0x55};
    unsigned char output_test_2[4] = {0x47, 0xBD, 0x7E, 0xAA};
    unsigned char output_test_3[4] = {0x8F, 0x7A, 0xFD, 0x54};
    unsigned char output_test_4[4] = {0x1E, 0xF5, 0xFA, 0xA9};
    unsigned char output_test_5[4] = {0x3D, 0xEB, 0xF5, 0x52};
    unsigned char output_test_6[4] = {0x7B, 0xD7, 0xEA, 0xA4};
    unsigned char output_test_7[4] = {0xF7, 0xAF, 0xD5, 0x48};

    unsigned char output[4];
    
    // 
    // run tests
    //
    unsigned int i;
    for (i=0; i<8; i++) {
        memmove(output, input, 4);
        liquid_lbcircshift( output, 4, i);
        switch (i) {
        case 0: CONTEND_SAME_DATA( output, output_test_0, 4 ); break;
        case 1: CONTEND_SAME_DATA( output, output_test_1, 4 ); break;
        case 2: CONTEND_SAME_DATA( output, output_test_2, 4 ); break;
        case 3: CONTEND_SAME_DATA( output, output_test_3, 4 ); break;
        case 4: CONTEND_SAME_DATA( output, output_test_4, 4 ); break;
        case 5: CONTEND_SAME_DATA( output, output_test_5, 4 ); break;
        case 6: CONTEND_SAME_DATA( output, output_test_6, 4 ); break;
        case 7: CONTEND_SAME_DATA( output, output_test_7, 4 ); break;
        default:;
        }
    }
}
// 
// AUTOTEST : test simple recovery of frame in noise
//
void qpacketmodem_test(unsigned int _payload_len,
                       int          _check,
                       int          _fec0,
                       int          _fec1,
                       int          _ms)
{
    // derived values
    unsigned int i;

    // create and configure packet encoder/decoder object
    qpacketmodem q = qpacketmodem_create();
    qpacketmodem_configure(q, _payload_len, _check, _fec0, _fec1, _ms);
    if (liquid_autotest_verbose)
        qpacketmodem_print(q);

    // initialize payload
    unsigned char payload_tx[_payload_len];
    unsigned char payload_rx[_payload_len];

    // initialize payload
    for (i=0; i<_payload_len; i++) {
        payload_tx[i] = rand() & 0xff;
        payload_rx[i] = rand() & 0xff;
    }

    // get frame length
    unsigned int frame_len = qpacketmodem_get_frame_len(q);

    // allocate memory for frame samples
    float complex frame[frame_len];

    // encode frame
    qpacketmodem_encode(q, payload_tx, frame);

    // decode frame
    int crc_pass = qpacketmodem_decode(q, frame, payload_rx);

    // destroy object
    qpacketmodem_destroy(q);

    // check to see that frame was recovered
    CONTEND_EQUALITY( crc_pass, 1 );
    CONTEND_SAME_DATA( payload_tx, payload_rx, _payload_len );
}
Esempio n. 12
0
void autotest_fft_shift_4()
{
    float complex x[] = {
        0 + 0*_Complex_I,
        1 + 1*_Complex_I,
        2 + 2*_Complex_I,
        3 + 3*_Complex_I
    };

    float complex test[] = {
        2 + 2*_Complex_I,
        3 + 3*_Complex_I,
        0 + 0*_Complex_I,
        1 + 1*_Complex_I
    };

    fft_shift(x,4);

    CONTEND_SAME_DATA(x,test,4*sizeof(float complex));
}
Esempio n. 13
0
// 
// AUTOTEST: Test matrixcf add
//
void autotest_matrixcf_add() {

    float complex x[6] = {
      2+  3*_I,  10+  9*_I,   1+  3*_I, 
      7+  2*_I,   8+  6*_I,   3+  1*_I
    };

    float complex y[6] = {
      7+  3*_I,   4+  8*_I,   6+  6*_I, 
      1+  9*_I,   7+ 10*_I,   5+  1*_I
    };

    float complex z[6];
    float complex ztest[6] = {
      9+  6*_I,  14+ 17*_I,   7+  9*_I, 
      8+ 11*_I,  15+ 16*_I,   8+  2*_I
    };

    matrixcf_add(x,y,z,2,3);

    CONTEND_SAME_DATA(z,ztest,sizeof(z));
}
Esempio n. 14
0
//
// AUTOTEST: Hamming (7,4) codec
//
void autotest_hamming74_codec()
{
    unsigned int n=4;
    unsigned char msg[] = {0x25, 0x62, 0x3F, 0x52};
    fec_scheme fs = LIQUID_FEC_HAMMING74;

    // create arrays
    unsigned int n_enc = fec_get_enc_msg_length(fs,n);
    unsigned char msg_dec[n];
    unsigned char msg_enc[n_enc];

    // create object
    fec q = fec_create(fs,NULL);
    if (liquid_autotest_verbose)
        fec_print(q);

    // encode message
    fec_encode(q, n, msg, msg_enc);
    
    // corrupt encoded message
    msg_enc[0] ^= 0x04; // position 5
#if 0
    msg_enc[1] ^= 0x04; //
    msg_enc[2] ^= 0x02; //
    msg_enc[3] ^= 0x01; //
    msg_enc[4] ^= 0x80; //
    msg_enc[5] ^= 0x40; //
    msg_enc[6] ^= 0x20; //
#endif

    // decode message
    fec_decode(q, n, msg_enc, msg_dec);

    // validate data are the same
    CONTEND_SAME_DATA(msg, msg_dec, n);

    // clean up objects
    fec_destroy(q);
}
Esempio n. 15
0
// floating point
void autotest_cbufferf()
{
    // input array of values
    float v[] = {1, 2, 3, 4, 5, 6, 7, 8};

    // output test arrays
    float test1[] = {1, 2, 3, 4};
    float test2[] = {3, 4, 1, 2, 3, 4, 5, 6, 7, 8};
    float test3[] = {3, 4, 5, 6, 7, 8};
    float test4[] = {3, 4, 5, 6, 7, 8, 1, 2, 3};
    float *r;                   // output read pointer
    unsigned int num_requested; // number of samples requested
    unsigned int num_read;      // number of samples read

    // create new circular buffer with 10 elements
    cbufferf q = cbufferf_create(10);
    // cbuffer: { <empty> }

    // part 1: write 4 elements to the buffer
    cbufferf_write(q, v, 4);
    // cbuffer: {1 2 3 4}

    // part 2: try to read 4 elements
    num_requested = 4;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,4);
    CONTEND_SAME_DATA(r,test1,4*sizeof(float));

    // part 3: release two elements, write 8 more, read 10
    cbufferf_release(q, 2);
    // cbuffer: {3 4}
    cbufferf_write(q, v, 8);
    // cbuffer: {3 4 1 2 3 4 5 6 7 8}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,10);
    CONTEND_SAME_DATA(r,test2,10*sizeof(float));

    // part 4: pop single element from buffer
    CONTEND_EQUALITY( cbufferf_size(q), 10    );
    cbufferf_pop(q, r);
    // cbuffer: {4 1 2 3 4 5 6 7 8}
    CONTEND_EQUALITY( cbufferf_size(q),  9    );
    CONTEND_EQUALITY( *r,                3.0f );

    // part 5: release three elements, and try reading 10
    cbufferf_release(q, 3);
    // cbuffer: {3 4 5 6 7 8}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,6);
    CONTEND_SAME_DATA(r,test3,6*sizeof(float));

    // part 6: test pushing multiple elements
    cbufferf_push(q, 1);
    cbufferf_push(q, 2);
    cbufferf_push(q, 3);
    // cbuffer: {3 4 5 6 7 8 1 2 3}
    num_requested = 10;
    cbufferf_read(q, num_requested, &r, &num_read);
    CONTEND_EQUALITY(num_read,9);
    CONTEND_SAME_DATA(r,test4,9*sizeof(float));

    // part 7: add one more element; buffer should be full
    CONTEND_EXPRESSION( cbufferf_is_full(q)==0 );
    cbufferf_push(q, 1);
    // cbuffer: {3 4 5 6 7 8 1 2 3 1}
    CONTEND_EXPRESSION( cbufferf_is_full(q)==1 );

    // memory leaks are evil
    cbufferf_destroy(q);
}
Esempio n. 16
0
//
// AUTOTEST: windowf
//
void autotest_windowf()
{
    float v[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
    float *r;   // reader pointer
    float x;    // temporary value holder
    unsigned int i;

    float test0[10] = {0,0,0,0,0,0,0,0,0,0};
    float test1[10] = {0,0,0,0,0,0,1,1,1,1};
    float test2[10] = {0,0,1,1,1,1,9,8,7,6};
    float test3[10] = {1,1,9,8,7,6,3,3,3,3};
    float test4[10] = {7,6,3,3,3,3,5,5,5,5};
    float test5[6]  = {3,3,5,5,5,5};
    float test6[6]  = {5,5,5,5,6,7};
    float test7[10] = {0,0,0,0,5,5,5,5,6,7};
    float test8[10] = {0,0,0,0,0,0,0,0,0,0};

    // create window
    // 0 0 0 0 0 0 0 0 0 0
    windowf w = windowf_create(10);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test0,10*sizeof(float));

    // push 4 elements
    // 0 0 0 0 0 0 1 1 1 1
    windowf_push(w, 1);
    windowf_push(w, 1);
    windowf_push(w, 1);
    windowf_push(w, 1);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test1,10*sizeof(float));

    // push 4 more elements
    // 0 0 1 1 1 1 9 8 7 6
    windowf_write(w, v, 4);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test2,10*sizeof(float));

    // push 4 more elements
    // 1 1 9 8 7 6 3 3 3 3
    windowf_push(w, 3);
    windowf_push(w, 3);
    windowf_push(w, 3);
    windowf_push(w, 3);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test3,10*sizeof(float));

    // test indexing operation
    windowf_index(w, 0, &x);    CONTEND_EQUALITY(x, 1);
    windowf_index(w, 1, &x);    CONTEND_EQUALITY(x, 1);
    windowf_index(w, 2, &x);    CONTEND_EQUALITY(x, 9);
    windowf_index(w, 3, &x);    CONTEND_EQUALITY(x, 8);
    windowf_index(w, 4, &x);    CONTEND_EQUALITY(x, 7);
    windowf_index(w, 5, &x);    CONTEND_EQUALITY(x, 6);
    windowf_index(w, 6, &x);    CONTEND_EQUALITY(x, 3);
    windowf_index(w, 7, &x);    CONTEND_EQUALITY(x, 3);
    windowf_index(w, 8, &x);    CONTEND_EQUALITY(x, 3);
    windowf_index(w, 9, &x);    CONTEND_EQUALITY(x, 3);

    // push 4 more elements
    // 7 6 3 3 3 3 5 5 5 5
    windowf_push(w, 5);
    windowf_push(w, 5);
    windowf_push(w, 5);
    windowf_push(w, 5);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test4,10*sizeof(float));
    if (liquid_autotest_verbose)
        windowf_debug_print(w);

    // recreate window (truncate to last 6 elements)
    // 3 3 5 5 5 5
    w = windowf_recreate(w,6);
    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test5,6*sizeof(float));

    // push 2 more elements
    // 5 5 5 5 6 7
    windowf_push(w, 6);
    windowf_push(w, 7);
    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test6,6*sizeof(float));

    // recreate window (extend to 10 elements)
    // 0 0 0 0 5 5 5 5 6 7
    w = windowf_recreate(w,10);
    windowf_read(w,&r);
    CONTEND_SAME_DATA(r,test7,10*sizeof(float));

    // reset
    // 0 0 0 0 0 0 0 0 0 0
    windowf_reset(w);

    windowf_read(w, &r);
    CONTEND_SAME_DATA(r,test8,10*sizeof(float));

    if (liquid_autotest_verbose) {
        // manual print
        printf("manual output:\n");
        for (i=0; i<10; i++)
            printf("%6u : %f\n", i, r[i]);

        windowf_debug_print(w);
    }

    windowf_destroy(w);

    printf("done.\n");
}