Esempio n. 1
0
//
// AUTOTEST: check RMSE for CVSD
//
void autotest_cvsd_rmse_sine() {
    unsigned int n=256;
    unsigned int nbits=3;
    float zeta=1.5f;
    float alpha=0.90f;

    // create cvsd codecs
    cvsd cvsd_encoder = cvsd_create(nbits,zeta,alpha);
    cvsd cvsd_decoder = cvsd_create(nbits,zeta,alpha);

    float phi=0.0f;
    float dphi=0.1f;
    unsigned int i;
    unsigned char b;
    float x,y;
    float rmse=0.0f;
    for (i=0; i<n; i++) {
        x = 0.5f*sinf(phi);
        b = cvsd_encode(cvsd_encoder, x); 
        y = cvsd_decode(cvsd_decoder, b); 

        rmse += (x-y)*(x-y);
        phi += dphi;
    }   

    rmse = 10*log10f(rmse/n);
    if (liquid_autotest_verbose)
        printf("cvsd rmse : %8.2f dB\n", rmse);
    CONTEND_LESS_THAN(rmse, -20.0f);

    // destroy cvsd codecs
    cvsd_destroy(cvsd_encoder);
    cvsd_destroy(cvsd_decoder);
}
Esempio n. 2
0
// 
// AUTOTEST: Gamma
//
void autotest_gamma()
{
    // error tolerance
    float tol = 1e-5f;

    // test vectors
    float v[12][2] = {
        {0.0001f, 9999.42288323161f     },
        {0.001f,   999.423772484595f    },
        {0.01f,     99.4325851191505f   },
        {0.1f,       9.51350769866873f  },
        {0.2f,       4.59084371199880f  },
        {0.5f,       1.77245385090552f  },
        {1.5f,       0.886226925452758f },
        {2.5f,       1.329340388179140f },
        {3.2f,       2.42396547993537f  },
        {4.1f,       6.81262286301667f  },
        {5.3f,      38.0779764499523f   },
        {12.0f, 39916800.0000000f       }};

    unsigned int i;
    for (i=0; i<12; i++) {
        // extract test vector
        float z = v[i][0];
        float g = v[i][1];

        // compute gamma
        float gamma = liquid_gammaf(z);

        // compute relative error
        float error = fabsf(gamma-g) / fabsf(g);

        // print results
        if (liquid_autotest_verbose)
            printf("  gamma(%12.4e) = %12.4e (expected %12.4e) %12.4e\n", z, gamma, g, error);

        // run test
        CONTEND_LESS_THAN(error, tol);
    }
}
Esempio n. 3
0
// 
// AUTOTEST : test multi-stage arbitrary resampler
//
void autotest_msresamp_crcf()
{
    // options
    unsigned int m = 13;        // filter semi-length (filter delay)
    float r=0.127115323f;       // resampling rate (output/input)
    float As=60.0f;             // resampling filter stop-band attenuation [dB]
    unsigned int n=1200;        // number of input samples
    float fx=0.0254230646f;     // complex input sinusoid frequency (0.2*r)
    //float bw=0.45f;             // resampling filter bandwidth
    //unsigned int npfb=64;       // number of filters in bank (timing resolution)

    unsigned int i;

    // number of input samples (zero-padded)
    unsigned int nx = n + m;

    // output buffer with extra padding for good measure
    unsigned int y_len = (unsigned int) ceilf(1.1 * nx * r) + 4;

    // arrays
    float complex x[nx];
    float complex y[y_len];

    // create resampler
    msresamp_crcf q = msresamp_crcf_create(r,As);

    // generate input signal
    float wsum = 0.0f;
    for (i=0; i<nx; i++) {
        // compute window
        float w = i < n ? kaiser(i, n, 10.0f, 0.0f) : 0.0f;

        // apply window to complex sinusoid
        x[i] = cexpf(_Complex_I*2*M_PI*fx*i) * w;

        // accumulate window
        wsum += w;
    }

    // resample
    unsigned int ny=0;
    unsigned int nw;
    for (i=0; i<nx; i++) {
        // execute resampler, storing in output buffer
        msresamp_crcf_execute(q, &x[i], 1, &y[ny], &nw);

        // increment output size
        ny += nw;
    }

    // clean up allocated objects
    msresamp_crcf_destroy(q);

    // 
    // analyze resulting signal
    //

    // check that the actual resampling rate is close to the target
    float r_actual = (float)ny / (float)nx;
    float fy = fx / r;      // expected output frequency

    // run FFT and ensure that carrier has moved and that image
    // frequencies and distortion have been adequately suppressed
    unsigned int nfft = 1 << liquid_nextpow2(ny);
    float complex yfft[nfft];   // fft input
    float complex Yfft[nfft];   // fft output
    for (i=0; i<nfft; i++)
        yfft[i] = i < ny ? y[i] : 0.0f;
    fft_run(nfft, yfft, Yfft, LIQUID_FFT_FORWARD, 0);
    fft_shift(Yfft, nfft);  // run FFT shift

    // find peak frequency
    float Ypeak = 0.0f;
    float fpeak = 0.0f;
    float max_sidelobe = -1e9f;     // maximum side-lobe [dB]
    float main_lobe_width = 0.07f;  // TODO: figure this out from Kaiser's equations
    for (i=0; i<nfft; i++) {
        // normalized output frequency
        float f = (float)i/(float)nfft - 0.5f;

        // scale FFT output appropriately
        Yfft[i] /= (r * wsum);
        float Ymag = 20*log10f( cabsf(Yfft[i]) );

        // find frequency location of maximum magnitude
        if (Ymag > Ypeak || i==0) {
            Ypeak = Ymag;
            fpeak = f;
        }

        // find peak side-lobe value, ignoring frequencies
        // within a certain range of signal frequency
        if ( fabsf(f-fy) > main_lobe_width )
            max_sidelobe = Ymag > max_sidelobe ? Ymag : max_sidelobe;
    }

    if (liquid_autotest_verbose) {
        // print results
        printf("  desired resampling rate   :   %12.8f\n", r);
        printf("  measured resampling rate  :   %12.8f    (%u/%u)\n", r_actual, ny, nx);
        printf("  peak spectrum             :   %12.8f dB (expected 0.0 dB)\n", Ypeak);
        printf("  peak frequency            :   %12.8f    (expected %-12.8f)\n", fpeak, fy);
        printf("  max sidelobe              :   %12.8f dB (expected at least %.2f dB)\n", max_sidelobe, -As);
    }
    CONTEND_DELTA(     r_actual, r,    0.01f ); // check actual output sample rate
    CONTEND_DELTA(     Ypeak,    0.0f, 0.25f ); // peak should be about 0 dB
    CONTEND_DELTA(     fpeak,    fy,   0.01f ); // peak frequency should be nearly 0.2
    CONTEND_LESS_THAN( max_sidelobe, -As );     // maximum side-lobe should be sufficiently low

#if 0
    // export results for debugging
    char filename[] = "msresamp_crcf_autotest.m";
    FILE*fid = fopen(filename,"w");
    fprintf(fid,"%% %s: auto-generated file\n",filename);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n");
    fprintf(fid,"r    = %12.8f;\n", r);
    fprintf(fid,"nx   = %u;\n", nx);
    fprintf(fid,"ny   = %u;\n", ny);
    fprintf(fid,"nfft = %u;\n", nfft);

    fprintf(fid,"Y = zeros(1,nfft);\n");
    for (i=0; i<nfft; i++)
        fprintf(fid,"Y(%3u) = %12.4e + j*%12.4e;\n", i+1, crealf(Yfft[i]), cimagf(Yfft[i]));

    fprintf(fid,"\n\n");
    fprintf(fid,"%% plot frequency-domain result\n");
    fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(f,20*log10(abs(Y)),'Color',[0.25 0.5 0.0],'LineWidth',2);\n");
    fprintf(fid,"grid on;\n");
    fprintf(fid,"xlabel('normalized frequency');\n");
    fprintf(fid,"ylabel('PSD [dB]');\n");
    fprintf(fid,"axis([-0.5 0.5 -120 20]);\n");

    fclose(fid);
    printf("results written to %s\n",filename);
#endif
}