1 //
2 // iirinterp_crcf_example.c
3 //
4 // This example demonstrates the iirinterp object (IIR interpolator)
5 // interface.
6 //
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include <getopt.h>
12 
13 #include "liquid.h"
14 
15 #define OUTPUT_FILENAME "iirinterp_crcf_example.m"
16 
17 // print usage/help message
usage()18 void usage()
19 {
20     printf("iirinterp_crcf_example:\n");
21     printf("  h     : print help\n");
22     printf("  k     : samples/symbol (interp factor), k > 1, default: 4\n");
23     printf("  n     : number of input samples, default: 64\n");
24 }
25 
26 
main(int argc,char * argv[])27 int main(int argc, char*argv[]) {
28     // options
29     unsigned int k = 4;             // interpolation factor
30     unsigned int num_samples = 64;  // number of input samples
31 
32     int dopt;
33     while ((dopt = getopt(argc,argv,"uhk:n:")) != EOF) {
34         switch (dopt) {
35         case 'h': usage();                      return 0;
36         case 'k': k           = atoi(optarg);   break;
37         case 'n': num_samples = atoi(optarg);   break;
38         default:
39             exit(1);
40         }
41     }
42 
43     // validate options
44     if (k < 2) {
45         fprintf(stderr,"error: %s, interp factor must be greater than 1\n", argv[0]);
46         exit(1);
47     } else if (num_samples < 1) {
48         fprintf(stderr,"error: %s, must have at least one data symbol\n", argv[0]);
49         usage();
50         return 1;
51     }
52 
53     // create interpolator from prototype
54     unsigned int order = 8;
55     iirinterp_crcf q = iirinterp_crcf_create_default(k,order);
56 
57     // derived values
58     float delay = iirinterp_crcf_groupdelay(q,0.0f);
59 
60     // generate input signal and interpolate
61     float complex x[  num_samples]; // input samples
62     float complex y[k*num_samples]; // output samples
63     unsigned int i;
64     for (i=0; i<num_samples; i++) {
65         // input signal (sinusoidal chirp)
66         x[i] = cexpf(_Complex_I*(-0.17f*i + 0.9*i*i/(float)num_samples));
67 
68         // apply window
69         x[i] *= (i < num_samples-5) ? hamming(i,num_samples) : 0.0f;
70 
71         // push through interpolator
72         iirinterp_crcf_execute(q, x[i], &y[k*i]);
73     }
74 
75     // destroy interpolator object
76     iirinterp_crcf_destroy(q);
77 
78 
79     //
80     // export output file
81     //
82     FILE * fid = fopen(OUTPUT_FILENAME,"w");
83     fprintf(fid,"%% %s: auto-generated file\n\n", OUTPUT_FILENAME);
84     fprintf(fid,"clear all;\n");
85     fprintf(fid,"close all;\n");
86     fprintf(fid,"k = %u;\n", k);
87     fprintf(fid,"delay = %f;\n", delay);
88     fprintf(fid,"num_samples = %u;\n", num_samples);
89     fprintf(fid,"x = zeros(1,  num_samples);\n");
90     fprintf(fid,"y = zeros(1,k*num_samples);\n");
91 
92     for (i=0; i<num_samples; i++)
93         fprintf(fid,"x(%4u) = %12.4e + j*%12.4e;\n", i+1, crealf(x[i]), cimagf(x[i]));
94 
95     for (i=0; i<k*num_samples; i++)
96         fprintf(fid,"y(%4u) = %12.4e + j*%12.4e;\n", i+1, k*crealf(y[i]), k*cimagf(y[i]));
97 
98     fprintf(fid,"\n\n");
99     fprintf(fid,"tx = [0:(  num_samples-1)];\n");
100     fprintf(fid,"ty = [0:(k*num_samples-1)]/k - delay;\n");
101     fprintf(fid,"figure;\n");
102     fprintf(fid,"subplot(2,1,1);\n");
103     fprintf(fid,"    plot(tx,real(x),'-s','MarkerSize',3,ty,real(y),'-s','MarkerSize',1);\n");
104     fprintf(fid,"    legend('input','interp','location','northeast');\n");
105     fprintf(fid,"    axis([0 num_samples -1.2 1.2]);\n");
106     fprintf(fid,"    xlabel('time');\n");
107     fprintf(fid,"    ylabel('real');\n");
108     fprintf(fid,"    grid on;\n");
109     fprintf(fid,"subplot(2,1,2);\n");
110     fprintf(fid,"    plot(tx,imag(x),'-s','MarkerSize',3,ty,imag(y),'-s','MarkerSize',1);\n");
111     fprintf(fid,"    legend('input','interp','location','northeast');\n");
112     fprintf(fid,"    axis([0 num_samples -1.2 1.2]);\n");
113     fprintf(fid,"    xlabel('time');\n");
114     fprintf(fid,"    ylabel('imag');\n");
115     fprintf(fid,"    grid on;\n");
116 
117     // power spectral density
118     fprintf(fid,"nfft = 1024;\n");
119     fprintf(fid,"fx   = [0:(nfft-1)]/nfft - 0.5;\n");
120     fprintf(fid,"fy   = k*fx;\n");
121     fprintf(fid,"X    = 20*log10(abs(fftshift(fft(x  ,nfft))));\n");
122     fprintf(fid,"Y    = 20*log10(abs(fftshift(fft(y/k,nfft))));\n");
123     fprintf(fid,"figure;\n");
124     fprintf(fid,"plot(fx,X,'LineWidth',2, fy,Y,'LineWidth',1);\n");
125     fprintf(fid,"legend('input','interp','location','northeast');\n");
126     fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
127     fprintf(fid,"ylabel('Power Spectral Density [dB]');\n");
128     fprintf(fid,"grid on;\n");
129 
130     fclose(fid);
131     printf("results written to %s.\n",OUTPUT_FILENAME);
132 
133     printf("done.\n");
134     return 0;
135 }
136