29 #define SAMPLE_RATE 48000 38 #include <boost/format.hpp> 42 #include <sys/types.h> 52 Histogram(
unsigned int nb,
float _min,
float _max) {
57 bucket_size = (_max - _min) / ((
float) num_buckets);
58 buckets =
new unsigned int[num_buckets];
59 underflow = 0; overflow = 0;
61 for(i = 0; i < num_buckets; i++) buckets[i] = 0;
65 if(samp < min) underflow++;
66 else if(samp > max) overflow++;
68 unsigned int idx = (
unsigned int) floor((samp - min) / bucket_size);
73 void dump(ostream & os,
const std::string & tag) {
74 os << boost::format(
"%s %f %d\n") % tag % (min - bucket_size) % underflow;
76 for(i = 0; i < num_buckets; i++) {
77 if(buckets[i] == 0)
continue;
78 float b = min + ((float) i) * bucket_size;
79 os << boost::format(
"%s %f %d\n") % tag % b % buckets[i];
81 os << boost::format(
"%s %f %d\n") % tag % (max + bucket_size) % overflow;
97 gettimeofday(&tp, NULL);
98 ret = ((double) tp.tv_sec) + 1e-6*((double)tp.tv_usec);
109 (void) argc; (void) argv;
113 std::complex<float> cinbuf[
BUFLEN];
114 std::complex<float> outbuf[
BUFLEN];
115 std::complex<float> coutbuf[
BUFLEN];
116 std::complex<float> checkbuf[
BUFLEN];
121 const int num_freqs = 8;
122 float angles[num_freqs];
123 float ang_incs[num_freqs];
128 for(i = 0; i < num_freqs; i++) {
130 long irand = random();
131 ang_incs[i] = M_PI * ((float) (3.535 * ((irand % 8) + 15))) / (0.82 * ((float) (
BUFLEN)));
135 for(k = 0; k < 20; k++) {
137 for(i = 0; i <
BUFLEN; i++) {
138 checkbuf[i] = std::complex<float>(0.0, 0.0);
140 cinbuf[i] = std::complex<float>(0.0, 0.0);
143 for(i = 0; i <
BUFLEN; i++) {
145 float x = ((float) (i + BUFLEN + k * BUFLEN)) / (4.0 * ((
float)
BUFLEN));
146 gain = 0.5 * (1.0 - cos(M_PI * x));
151 for(j = 0; j < num_freqs; j++) {
152 inbuf[i] += gain * sin(angles[j]);
153 cinbuf[i] += std::complex<float>(gain * sin(angles[j]),0.0);
154 checkbuf[i] += std::complex<float>(gain * sin(angles[j]), -1.0 * gain * cos(angles[j]));
155 angles[j] += ang_incs[j];
156 if(angles[j] > M_PI) angles[j] -= (2.0 * M_PI);
161 htR.
apply(inbuf, outbuf,
false, 1.0);
162 htC.
apply(cinbuf, coutbuf,
true, 1.0);
165 for(i = 0; i <
BUFLEN; i++) {
166 std::cout << boost::format(
"ZZZ: %d %f %f %f %f %f %f\n")
167 % (i + k *
BUFLEN) % outbuf[i].real() % outbuf[i].imag() % coutbuf[i].real() % coutbuf[i].imag() % checkbuf[i].real() % checkbuf[i].imag();
176 for(k = 0; k < 20; k++) {
177 for(i = 0; i <
BUFLEN; i++) {
178 checkbuf[i] = std::complex<float>(0.0, 0.0);
179 cinbuf[i] = std::complex<float>(0.0, 0.0);
182 for(i = 0; i <
BUFLEN; i++) {
184 float x = ((float) (i + BUFLEN + k * BUFLEN)) / (4.0 * ((
float)
BUFLEN));
185 gain = 0.5 * (1.0 - cos(M_PI * x));
190 for(j = 0; j < num_freqs; j++) {
191 cinbuf[i] += gain * std::complex<float>(sin(angles[j]), cos(angles[j]));
194 checkbuf[i] += gain * std::complex<float>(sin(angles[j]), -1.0 * cos(angles[j]));
197 angles[j] += ang_incs[j];
198 if(angles[j] > M_PI) angles[j] -= (2.0 * M_PI);
203 htDemod.
applyIQ(cinbuf, outbuf, 1.0);
207 for(i = 0; i <
BUFLEN; i++) {
208 std::cout << boost::format(
"MMM: %d %f %f %f %f %f %f\n")
209 % (i + k *
BUFLEN) % outbuf[i].real() % outbuf[i].imag() % cinbuf[i].real() % cinbuf[i].imag() % checkbuf[i].real() % checkbuf[i].imag();
229 (void) argc; (void) argv;
242 std::complex<float> analytic_U_inbuf[buflen];
243 std::complex<float> analytic_L_inbuf[buflen];
244 std::complex<float> usb_outbuf[buflen];
245 std::complex<float> lsb_outbuf[buflen];
250 const int num_freqs = 16;
251 float angles[num_freqs];
252 float ang_incs[num_freqs];
257 for(i = 0; i < num_freqs; i++) {
259 long irand = random();
262 float frand = ((float) (irand & 0xffff)) / (8.0 * 65536.0);
263 ang_incs[i] = frand * M_PI;
266 ang_incs[0] = 0.01 * M_PI;
273 int trial_count = 10;
274 int ignore_buffer_count = 1;
275 for(k = 0; k < trial_count; k++) {
277 for(j = 0; j < buflen; j++) {
280 for(i = 0; i < num_freqs; i++) {
281 for(j = 0; j < buflen; j++) {
282 inbuf[j] += sin(angles[i]);
283 angles[i] += ang_incs[i];
288 HT_ui.
apply(inbuf, analytic_U_inbuf,
false, 1.0);
289 HT_li.
apply(inbuf, analytic_L_inbuf,
true, 1.0);
290 HT_usb.
applyIQ(analytic_U_inbuf, usb_outbuf, 1.0);
291 HT_lsb.
applyIQ(analytic_L_inbuf, lsb_outbuf, 1.0);
295 if(k >= ignore_buffer_count) {
297 for(j = 0; j < buflen; j++) {
298 norm += (inbuf[j] * inbuf[j]);
301 for(j = 0; j < buflen; j++) {
302 float usb_sum, lsb_diff;
303 usb_sum = usb_outbuf[j].real() + usb_outbuf[j].imag();
304 lsb_diff = lsb_outbuf[j].real() - lsb_outbuf[j].imag();
306 usb_sum_err.
record(usb_sum / norm);
307 lsb_diff_err.
record(lsb_diff / norm);
309 std::cerr << boost::format(
"%d %f %f %f %f %f %f %f %f %f %f\n") %
312 usb_outbuf[j].real() % usb_outbuf[j].imag() %
313 lsb_outbuf[j].real() % lsb_outbuf[j].imag() %
314 analytic_U_inbuf[j].real() % analytic_U_inbuf[j].imag() %
315 analytic_L_inbuf[j].real() % analytic_L_inbuf[j].imag()
322 std::cout << boost::format(
"# Dumps histograms of USB and LSB normalized error\n# -- all should be clustered around 0.0 -- normalized to mean squared amplitude.\n");
323 usb_sum_err.
dump(std::cout, std::string(
"USB: "));
324 lsb_diff_err.
dump(std::cout, std::string(
"LSB: "));
335 (void) argc; (void) argv;
346 float rf_inbuf[buflen];
349 std::complex<float> transform_buf[buflen];
354 const int num_freqs = 16;
355 float angles[num_freqs];
356 float ang_incs[num_freqs];
361 for(i = 0; i < num_freqs; i++) {
363 long irand = random();
366 float frand = ((float) (irand & 0xffff)) / (64.0 * 65536.0);
367 ang_incs[i] = frand * M_PI;
370 ang_incs[0] = 0.01 * M_PI;
373 float phase_incr = M_PI / 100.0;
377 float carrier_freq = M_PI / 20.0;
378 float tx_carrier_angle = 0.0;
379 float rx_carrier_angle = 0.0;
382 int trial_count = 10;
383 int ignore_buffer_count = 1;
384 for(k = 0; k < trial_count; k++) {
386 for(j = 0; j < buflen; j++) {
389 for(i = 0; i < num_freqs; i++) {
390 for(j = 0; j < buflen; j++) {
391 inbuf[j] += sin(angles[i]);
392 angles[i] += ang_incs[i];
396 for(j = 0; j < buflen; j++) {
397 rf_inbuf[j] = sin(tx_carrier_angle + inbuf[j] * phase_incr);
398 tx_carrier_angle += carrier_freq;
402 HT.
apply(rf_inbuf, transform_buf,
false, 1.0);
405 for(j = 0; j < buflen; j++) {
406 std::complex<float> rx_carrier = std::complex<float>(sin(rx_carrier_angle), cos(rx_carrier_angle));
407 rx_carrier_angle += carrier_freq;
408 transform_buf[j] = transform_buf[j] * rx_carrier;
412 if(k >= ignore_buffer_count) {
414 for(j = 0; j < buflen; j++) {
415 norm += (inbuf[j] * inbuf[j]);
418 for(j = 0; j < buflen; j++) {
421 demod = atan2(transform_buf[j].imag(), transform_buf[j].real());
423 std::cerr << boost::format(
"PM %d %f %f %f %f %f\n") %
428 transform_buf[j].real() % transform_buf[j].imag();
437 int main(
int argc,
char * argv[])
int doPMTest(int argc, char *argv[])
doPMTest – run a Phase Modulated signal through a hilbert transform shift to baseband, then demodulate.
This is an overlap-and-save frequency domain implementation of a general FIR filter widget...
void dump(ostream &os, const std::string &tag)
Histogram(unsigned int nb, float _min, float _max)
int dumpTest(int argc, char *argv[])
int doSSBTest(int argc, char *argv[])
Applying HT twice to a real valued signal f(t) will produce a delayed version of -1 * f(t + d) at its...
int main(int argc, char *argv[])