Example #1
0
void gmskdem_demodulate(gmskdem _q,
                        float complex * _x,
                        unsigned int * _s)
{
    // increment symbol counter
    _q->num_symbols_demod++;

    // run matched filter
    unsigned int i;
    float phi;
    float d_hat;
    for (i=0; i<_q->k; i++) {
        // compute phase difference
        phi = cargf( conjf(_q->x_prime)*_x[i] );
        _q->x_prime = _x[i];

        // run through matched filter
#if GMSKDEM_USE_EQUALIZER
        eqlms_rrrf_push(_q->eq, phi);
#else
        firfilt_rrrf_push(_q->filter, phi);
#endif

#if DEBUG_GMSKDEM
        // compute output
        float d_tmp;
#  if GMSKDEM_USE_EQUALIZER
        eqlms_rrrf_execute(_q->eq, &d_tmp);
#  else
        firfilt_rrrf_execute(_q->filter, &d_tmp);
#  endif
        windowf_push(_q->debug_mfout, d_tmp);
#endif

        // decimate by k
        if ( i != 0 ) continue;

#if GMSKDEM_USE_EQUALIZER
        // compute filter/equalizer output
        eqlms_rrrf_execute(_q->eq, &d_hat);
#else
        // compute filter output
        firfilt_rrrf_execute(_q->filter, &d_hat);
#endif
    }

    // make decision
    *_s = d_hat > 0.0f ? 1 : 0;

#if GMSKDEM_USE_EQUALIZER
    // update equalizer, after appropriate delay
    if (_q->num_symbols_demod >= 2*_q->m) {
        // compute expected output, scaling by samples/symbol
        float d_prime = d_hat > 0 ? _q->k_inv : -_q->k_inv;
        eqlms_rrrf_step(_q->eq, d_prime, d_hat);
    }
#endif
}
int main() {
    // options
    unsigned int h_len=17;  // filter length
    float fc=0.2f;          // filter cutoff
    float As=30.0f;         // stop-band attenuation [dB]
    float mu=0.0f;          // timing offset
    unsigned int n=64;      // number of random input samples

    // derived values
    unsigned int num_samples = n + h_len;

    // arrays
    float x[num_samples];   // filter input
    float y[num_samples];   // filter output

    unsigned int i;
    float h[h_len];
    liquid_firdes_kaiser(h_len,fc,As,mu,h);
    firfilt_rrrf f = firfilt_rrrf_create(h,h_len);
    firfilt_rrrf_print(f);

    for (i=0; i<num_samples; i++) {
        // generate noise
        x[i] = (i<n) ? randnf()/sqrtf(n/2) : 0.0f;

        firfilt_rrrf_push(f, x[i]);
        firfilt_rrrf_execute(f, &y[i]); 

        printf("x[%4u] = %12.8f, y[%4u] = %12.8f;\n", i, x[i], i, y[i]);
    }   

    // destroy filter object
    firfilt_rrrf_destroy(f);

    // 
    // export results
    //
    FILE*fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% firfilt_rrrf_example.m: auto-generated file\n\n");
    fprintf(fid,"clear all;\nclose all;\n\n");
    fprintf(fid,"h_len=%u;\nn=%u;\n", h_len, n);
    
    for (i=0; i<h_len; i++)
        fprintf(fid,"h(%4u) = %12.4e;\n", i+1, h[i]);

    for (i=0; i<num_samples; i++)
        fprintf(fid,"x(%4u) = %12.4e; y(%4u) = %12.4e;\n", i+1, x[i], i+1, y[i]);

    fprintf(fid,"nfft=512;\n");
    fprintf(fid,"H=20*log10(abs(fftshift(fft(h,nfft))));\n");
    fprintf(fid,"X=20*log10(abs(fftshift(fft(x,nfft))));\n");
    fprintf(fid,"Y=20*log10(abs(fftshift(fft(y,nfft))));\n");
    fprintf(fid,"f=[0:(nfft-1)]/nfft-0.5;\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(f,X,'Color',[0.3 0.3 0.3],...\n");
    fprintf(fid,"     f,Y,'LineWidth',2,...\n");
    fprintf(fid,"     f,H,'-b','LineWidth',2);\n");
    fprintf(fid,"axis([-0.5 0.5 -80 40]);\n");
    fprintf(fid,"grid on;\nxlabel('normalized frequency');\nylabel('PSD [dB]');\n");
    fprintf(fid,"legend('noise','filtered noise','filter prototype',1);");

    fclose(fid);
    printf("results written to %s\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
int main(int argc, char*argv[])
{
    // options
    unsigned int h_len=19;          // filter length
    unsigned int p=5;               // polynomial order
    float fc=0.45f;                 // filter cutoff
    float As=60.0f;                 // stop-band attenuation [dB]
    float mu=0.1f;                  // fractional sample delay
    unsigned int num_samples=60;    // number of samples to evaluate
    int verbose = 0;                // verbose output?

    int dopt;
    while ((dopt = getopt(argc,argv,"hvt:")) != EOF) {
        switch (dopt) {
        case 'h': usage();              return 0;
        case 'v': verbose = 1;          break;
        case 't': mu = atof(optarg);    break;
        default:
            exit(1);
        }
    }

    // data arrays
    float x[num_samples];           // input data array
    float y[num_samples];           // output data array

    // create and initialize Farrow filter object
    firfarrow_rrrf f = firfarrow_rrrf_create(h_len, p, fc, As);
    firfarrow_rrrf_set_delay(f, mu);

    unsigned int i;

    // generate input (filtered noise)
    float hx[21];
    liquid_firdes_kaiser(15, 0.1, 60, 0, hx);
    firfilt_rrrf fx = firfilt_rrrf_create(hx, 15);
    for (i=0; i<num_samples; i++) {
        firfilt_rrrf_push(fx, i < 40 ? randnf() : 0.0f);
        firfilt_rrrf_execute(fx, &x[i]);
    }
    firfilt_rrrf_destroy(fx);

    // push input through filter
    for (i=0; i<num_samples; i++) {
        firfarrow_rrrf_push(f, x[i]);
        firfarrow_rrrf_execute(f, &y[i]);
    }

    // destroy Farrow filter object
    firfarrow_rrrf_destroy(f);

    FILE*fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\nclose all;\n\n");
    fprintf(fid,"h_len = %u;\n", h_len);
    fprintf(fid,"mu = %f;\n", mu);
    fprintf(fid,"num_samples = %u;\n", num_samples);

    for (i=0; i<num_samples; i++) {
        fprintf(fid,"x(%4u) = %12.4e; y(%4u) = %12.4e;\n", i+1, x[i], i+1, y[i]);
    }

    // plot the results
    fprintf(fid,"\n\n");
    fprintf(fid,"figure;\n");
    fprintf(fid,"tx = 0:(num_samples-1);     %% input time scale\n");
    fprintf(fid,"ty = tx - (h_len-1)/2 + mu; %% output time scale\n");
    fprintf(fid,"plot(tx, x,'-s','MarkerSize',3, ...\n");
    fprintf(fid,"     ty, y,'-s','MarkerSize',3);\n");
    fprintf(fid,"legend('input','output',0);\n");

    fclose(fid);
    printf("results written to %s\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
Example #4
0
int main() {
    // spectral periodogram options
    unsigned int nfft        =   1024;  // spectral periodogram FFT size
    unsigned int num_samples =   4000;  // number of samples
    float        beta        =  10.0f;  // Kaiser-Bessel window parameter
    float        noise_floor = -60.0f;  // noise floor [dB]
    float        alpha       =   0.1f;  // PSD estimate bandwidth

    unsigned int i;

    // derived values
    float nstd = powf(10.0f, noise_floor/20.0f);

    // create spectral periodogram
    unsigned int window_size = nfft/2;  // spgramf window size
    spgramf q = spgramf_create_kaiser(nfft, window_size, beta);

    // generate signal (filter with frequency offset)
    unsigned int  h_len = 91;       // filter length
    float         fc    = 0.07f;    // filter cut-off frequency
    float         f0    = 0.20f;    // filter center frequency
    float         As    = 60.0f;    // filter stop-band attenuation
    float         h[h_len];         // filter coefficients
    liquid_firdes_kaiser(h_len, fc, As, 0, h);
    // add frequency offset
    for (i=0; i<h_len; i++)
        h[i] *= cosf(2*M_PI*f0*i);
    firfilt_rrrf filter = firfilt_rrrf_create(h, h_len);
    firfilt_rrrf_set_scale(filter, 2.0f*fc);

    for (i=0; i<num_samples; i++) {
        // generate random sample
        float x = randnf();

        // filter
        float y = 0;
        firfilt_rrrf_push(filter, x);
        firfilt_rrrf_execute(filter, &y);

        // add noise
        y += nstd * randnf();

        // push resulting sample through periodogram
        spgramf_accumulate_psd(q, &y, alpha, 1);
    }

    // compute power spectral density output
    float psd[nfft];
    spgramf_write_accumulation(q, psd);

    // destroy objects
    firfilt_rrrf_destroy(filter);
    spgramf_destroy(q);

    // 
    // export output file
    //
    FILE * fid = fopen(OUTPUT_FILENAME,"w");
    fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
    fprintf(fid,"clear all;\n");
    fprintf(fid,"close all;\n\n");
    fprintf(fid,"nfft = %u;\n", nfft);
    fprintf(fid,"f    = [0:(nfft-1)]/nfft - 0.5;\n");
    fprintf(fid,"H    = zeros(1,nfft);\n");
    fprintf(fid,"noise_floor = %12.6f;\n", noise_floor);
    
    for (i=0; i<nfft; i++)
        fprintf(fid,"H(%6u) = %12.4e;\n", i+1, psd[i]);

    fprintf(fid,"figure;\n");
    fprintf(fid,"plot(f, H, '-', 'LineWidth',1.5);\n");
    fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
    fprintf(fid,"ylabel('Power Spectral Density [dB]');\n");
    fprintf(fid,"grid on;\n");
    fprintf(fid,"ymin = 10*floor([noise_floor-20]/10);\n");
    fprintf(fid,"ymax = 10*floor([noise_floor+80]/10);\n");
    fprintf(fid,"axis([-0.5 0.5 ymin ymax]);\n");

    fclose(fid);
    printf("results written to %s.\n", OUTPUT_FILENAME);

    printf("done.\n");
    return 0;
}
Example #5
0
void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *audioOut) {
    ModemKitFMStereo *fmkit = (ModemKitFMStereo *)kit;
    size_t bufSize = input->data.size();
    liquid_float_complex u, v, w, x, y;
    
    double audio_resample_ratio = fmkit->audioResampleRatio;
    
    if (demodOutputData.size() != bufSize) {
        if (demodOutputData.capacity() < bufSize) {
            demodOutputData.reserve(bufSize);
        }
        demodOutputData.resize(bufSize);
    }
    
    size_t audio_out_size = (size_t)ceil((double) (bufSize) * audio_resample_ratio) + 512;
    
    freqdem_demodulate_block(demodFM, &input->data[0], bufSize, &demodOutputData[0]);
    
    if (resampledOutputData.size() != audio_out_size) {
        if (resampledOutputData.capacity() < audio_out_size) {
            resampledOutputData.reserve(audio_out_size);
        }
        resampledOutputData.resize(audio_out_size);
    }
    
    unsigned int numAudioWritten;
    
    msresamp_rrrf_execute(fmkit->audioResampler, &demodOutputData[0], bufSize, &resampledOutputData[0], &numAudioWritten);
    
    if (demodStereoData.size() != bufSize) {
        if (demodStereoData.capacity() < bufSize) {
            demodStereoData.reserve(bufSize);
        }
        demodStereoData.resize(bufSize);
    }
    
    float phase_error = 0;
    
    for (size_t i = 0; i < bufSize; i++) {
        // real -> complex
        firhilbf_r2c_execute(fmkit->firStereoR2C, demodOutputData[i], &x);
        
        // 19khz pilot band-pass
        iirfilt_crcf_execute(fmkit->iirStereoPilot, x, &v);
        nco_crcf_cexpf(fmkit->stereoPilot, &w);
        
        w.imag = -w.imag; // conjf(w)
        
        // multiply u = v * conjf(w)
        u.real = v.real * w.real - v.imag * w.imag;
        u.imag = v.real * w.imag + v.imag * w.real;
        
        // cargf(u)
        phase_error = atan2f(u.imag,u.real);
        
        // step pll
        nco_crcf_pll_step(fmkit->stereoPilot, phase_error);
        nco_crcf_step(fmkit->stereoPilot);
        
        // 38khz down-mix
        nco_crcf_mix_down(fmkit->stereoPilot, x, &y);
        nco_crcf_mix_down(fmkit->stereoPilot, y, &x);
        
        // complex -> real
        firhilbf_c2r_execute(fmkit->firStereoC2R, x, &demodStereoData[i]);
    }
    
    //            std::cout << "[PLL] phase error: " << phase_error;
    //            std::cout << " freq:" << (((nco_crcf_get_frequency(stereoPilot) / (2.0 * M_PI)) * inp->sampleRate)) << std::endl;
    
    if (audio_out_size != resampledStereoData.size()) {
        if (resampledStereoData.capacity() < audio_out_size) {
            resampledStereoData.reserve(audio_out_size);
        }
        resampledStereoData.resize(audio_out_size);
    }
    
    msresamp_rrrf_execute(fmkit->stereoResampler, &demodStereoData[0], bufSize, &resampledStereoData[0], &numAudioWritten);
    
    audioOut->channels = 2;
    if (audioOut->data.capacity() < (numAudioWritten * 2)) {
        audioOut->data.reserve(numAudioWritten * 2);
    }
    audioOut->data.resize(numAudioWritten * 2);
    for (size_t i = 0; i < numAudioWritten; i++) {
        float l, r;
        float ld, rd;

        if (fmkit->demph) {
            iirfilt_rrrf_execute(fmkit->iirDemphL, 0.568f * (resampledOutputData[i] - (resampledStereoData[i])), &ld);
            iirfilt_rrrf_execute(fmkit->iirDemphR, 0.568f * (resampledOutputData[i] + (resampledStereoData[i])), &rd);
            
            firfilt_rrrf_push(fmkit->firStereoLeft, ld);
            firfilt_rrrf_execute(fmkit->firStereoLeft, &l);
            
            firfilt_rrrf_push(fmkit->firStereoRight, rd);
            firfilt_rrrf_execute(fmkit->firStereoRight, &r);
        } else {
            firfilt_rrrf_push(fmkit->firStereoLeft, 0.568f * (resampledOutputData[i] - (resampledStereoData[i])));
            firfilt_rrrf_execute(fmkit->firStereoLeft, &l);
            
            firfilt_rrrf_push(fmkit->firStereoRight, 0.568f * (resampledOutputData[i] + (resampledStereoData[i])));
            firfilt_rrrf_execute(fmkit->firStereoRight, &r);
        }
        
        audioOut->data[i * 2] = l;
        audioOut->data[i * 2 + 1] = r;
    }
}