1 //
2 // msourcecf_example.c
3 //
4 // This example demonstrates generating multiple signal sources simultaneously
5 // for testing using the msource (multi-source) family of objects.
6 //
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <math.h>
11 
12 #include "liquid.h"
13 
14 #define OUTPUT_FILENAME "msourcecf_example.m"
15 
16 // user-defined callback; generate tones
callback(void * _userdata,float complex * _v,unsigned int _n)17 int callback(void *          _userdata,
18              float complex * _v,
19              unsigned int    _n)
20 {
21     unsigned int * counter = (unsigned int*)_userdata;
22     unsigned int i;
23     for (i=0; i<_n; i++) {
24         _v[i] = *counter==0 ? 1 : 0;
25         *counter = (*counter+1) % 8;
26     }
27     return 0;
28 }
29 
main()30 int main()
31 {
32     // msource parameters
33     int          ms     = LIQUID_MODEM_QPSK;    // linear modulation scheme
34     unsigned int m      =    12;                // modulation filter semi-length
35     float        beta   = 0.30f;                // modulation filter excess bandwidth factor
36     float        bt     = 0.35f;                // GMSK filter bandwidth-time factor
37 
38     // spectral periodogram options
39     unsigned int nfft        =   2400;  // spectral periodogram FFT size
40     unsigned int num_samples =  48000;  // number of samples
41 
42     // create spectral periodogram
43     spgramcf periodogram = spgramcf_create_default(nfft);
44 
45     unsigned int buf_len = 1024;
46     float complex buf[buf_len];
47 
48     // create multi-signal source generator
49     msourcecf gen = msourcecf_create_default();
50 
51     // add signals     (gen,  fc,   bw,    gain, {options})
52     msourcecf_add_noise(gen,  0.0f, 1.00f, -40);               // wide-band noise
53     msourcecf_add_noise(gen,  0.0f, 0.20f,   0);               // narrow-band noise
54     msourcecf_add_tone (gen, -0.4f, 0.00f,  20);               // tone
55     msourcecf_add_modem(gen,  0.2f, 0.10f,   0, ms, m, beta);  // modulated data (linear)
56     msourcecf_add_gmsk (gen, -0.2f, 0.05f,   0, m, bt);        // modulated data (GMSK)
57     unsigned int counter = 0;
58     msourcecf_add_user (gen,  0.4f, 0.15f, -10, (void*)&counter, callback); // tones
59 
60     // print source generator object
61     msourcecf_print(gen);
62 
63     unsigned int total_samples = 0;
64     while (total_samples < num_samples) {
65         // write samples to buffer
66         msourcecf_write_samples(gen, buf, buf_len);
67 
68         // push resulting sample through periodogram
69         spgramcf_write(periodogram, buf, buf_len);
70 
71         // accumulated samples
72         total_samples += buf_len;
73     }
74     printf("total samples: %u\n", total_samples);
75 
76     // compute power spectral density output
77     float psd[nfft];
78     spgramcf_get_psd(periodogram, psd);
79 
80     // destroy objects
81     msourcecf_destroy(gen);
82     spgramcf_destroy(periodogram);
83 
84     //
85     // export output file
86     //
87     FILE * fid = fopen(OUTPUT_FILENAME,"w");
88     fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
89     fprintf(fid,"clear all;\n");
90     fprintf(fid,"close all;\n\n");
91     fprintf(fid,"nfft = %u;\n", nfft);
92     fprintf(fid,"f    = [0:(nfft-1)]/nfft - 0.5;\n");
93     fprintf(fid,"H    = zeros(1,nfft);\n");
94 
95     unsigned int i;
96     for (i=0; i<nfft; i++)
97         fprintf(fid,"H(%6u) = %12.4e;\n", i+1, psd[i]);
98 
99     fprintf(fid,"figure;\n");
100     fprintf(fid,"plot(f, H, '-', 'LineWidth',1.5);\n");
101     fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
102     fprintf(fid,"ylabel('Power Spectral Density [dB]');\n");
103     fprintf(fid,"grid on;\n");
104     //fprintf(fid,"axis([-0.5 0.5 -60 40]);\n");
105     fprintf(fid,"axis([-0.5 0.5 -80 40]);\n");
106 
107     fclose(fid);
108     printf("results written to %s.\n", OUTPUT_FILENAME);
109     return 0;
110 }
111 
112