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