Root/sal/sal.cpp

Source at commit 57b53c61c1b37a913fc963c3c0bec0364efbcb7e created 5 years 10 months ago.
By Werner Almesberger, ircstat/ML: update for 2014-01
1#include <stdint.h>
2#include <assert.h> /* sheer abuse */
3#include <math.h>
4
5#include <usrp2/usrp2.h>
6#include <usrp2/rx_nop_handler.h>
7#include <usrp2/copiers.h>
8
9#include <fftw3.h>
10
11#include "SDL.h"
12#include "SDL_gfxPrimitives.h"
13
14
15//#define N 1024
16#define XX 100
17#define N (1024*XX)
18#define AVG 1
19
20
21#define SCALE (2*XX)
22#define XRES (N/SCALE)
23#define YRES (768*XX/SCALE)
24#define DECIMATION 16
25
26static fftw_plan plan;
27static fftw_complex *in, *out;
28static double *w;
29static SDL_Surface *surf;
30
31
32#define SIZE (surf->h*surf->pitch)
33
34
35static int frames = 0;
36static int paws = 0;
37static int y_scale = 60;
38static uint32_t *bg = NULL;
39static long rate;
40static int snapshot = 0;
41static int avg_mode = 1;
42
43
44static void draw(const double *s)
45{
46    int i, x, y, first, last;
47
48    if (!bg)
49        bg = (uint32_t *) calloc(SIZE, 1);
50    if (paws)
51        return;
52    SDL_LockSurface(surf);
53    memcpy(surf->pixels, bg, SIZE);
54    for (y = y_scale; y < YRES; y += y_scale)
55        hlineColor(surf, 0, XRES-1, y, 0x008040ff);
56    uint32_t color = snapshot ? 0xff4000ff : 0xffffffff;
57    last = YRES-1;
58    for (i = 0; i != XRES; i++) {
59        y = s[i]*y_scale;
60        y = YRES-y+4*y_scale;
61        if (y < 0)
62            y = 0;
63        if (y >= YRES)
64            y = YRES-1;
65        x = (i+XRES/2) % XRES;
66        if (i)
67            vlineColor(surf, x, last, y, color);
68        if (!i)
69            first = y;
70        last = y;
71    }
72    vlineColor(surf, x+1, first, last, color);
73    if (snapshot) {
74        memcpy(bg, surf->pixels, SIZE);
75        snapshot = 0;
76    }
77    SDL_UnlockSurface(surf);
78    SDL_UpdateRect(surf, 0, 0, 0, 0);
79    frames++;
80}
81
82
83static void collect(void)
84{
85    static double sum[N];
86    static int cnt = 0;
87    int i, x, j;
88
89    i = 0;
90    for (x = 0; x != XRES; x++)
91        for (j = 0; j != SCALE; j++) {
92            double s = pow(out[i][0], 2)+pow(out[i][1], 2);
93
94            if (avg_mode)
95                sum[x] += s;
96            else {
97                if (sum[x] < s)
98                    sum[x] = s;
99            }
100            i++;
101        }
102    if (++cnt != AVG)
103        return;
104    cnt = 0;
105    for (i = 0; i != XRES; i++)
106        if (avg_mode)
107            sum[i] = log(sum[i]/AVG/SCALE)/log(10);
108        else
109            sum[i] = log(sum[i])/log(10);
110    draw(sum);
111    memset(sum, 0, sizeof(sum));
112}
113
114
115class rx : public usrp2::rx_nop_handler
116{
117public:
118    rx(uint64_t max_samples) : usrp2::rx_nop_handler(max_samples)
119    {
120    }
121
122    bool operator()(const uint32_t *items, size_t nitems,
123        const usrp2::rx_metadata *metadata);
124
125    ~rx(void)
126    {
127    }
128
129};
130
131
132bool rx::operator()(const uint32_t *items, size_t nitems,
133        const usrp2::rx_metadata *metadata)
134{
135    static std::complex<int16_t> host_items[N];
136    static size_t have = 0, copy, over;
137    bool ok;
138    size_t i;
139
140    ok = rx_nop_handler::operator()(items, nitems, metadata);
141    copy = N-have;
142    if (copy > nitems)
143        copy = nitems;
144    usrp2::copy_u2_16sc_to_host_16sc(copy, items, host_items+have);
145//fprintf(stderr, "nitems %u have %u copy %u\n", (unsigned) nitems, (unsigned) have, (unsigned) copy);
146    have += copy;
147    if (have == N) {
148        for (i = 0; i != nitems; i++) {
149            in[i][0] = host_items[i].real()*w[i];
150            in[i][1] = host_items[i].imag()*w[i];
151        }
152        fftw_execute(plan);
153        collect();
154        have = 0;
155    }
156    over = nitems-copy;
157    if (over)
158        usrp2::copy_u2_16sc_to_host_16sc(over, items+copy,
159            host_items+have);
160    have += over;
161    return ok;
162}
163
164
165static int key(SDLKey sym)
166{
167    switch (sym) {
168    case SDLK_a:
169        avg_mode = 1;
170        break;
171    case SDLK_c:
172        memset(bg, 0, SIZE);
173        break;
174    case SDLK_f:
175        fprintf(stderr, "%d\n", frames);
176        break;
177    case SDLK_m:
178        avg_mode = 0;
179        break;
180    case SDLK_p:
181        paws = !paws;
182        break;
183    case SDLK_q:
184        return 1;
185    case SDLK_s:
186        memset(bg, 0, SIZE);
187        snapshot = 1;
188        break;
189    default:
190        break;
191    }
192    return 0;
193}
194
195
196static void make_window(void)
197{
198    int i;
199
200    w = (double *) calloc(N, sizeof(double));
201    for (i = 0; i != N; i++)
202// hamming
203        w[i] = 0.54-0.46*cos(M_PI*2*i/(N-1));
204// hann w[i] = 0.5-0.5*cos(M_PI*2*i/(N-1));
205// blackman w[i] = 0.42-0.5*cos(2*M_PI*i/(N-1))+0.08*cos(4*M_PI*i/(N-1));
206}
207
208
209int main(void)
210{
211    usrp2::usrp2::sptr u;
212    usrp2::rx_nop_handler::sptr handler;
213    usrp2::tune_result tr;
214
215    handler = usrp2::rx_nop_handler::sptr(new rx(N));
216    u = usrp2::usrp2::make("eth0", "");
217    assert(u->stop_rx_streaming());
218    assert(u->set_rx_gain(46));
219    assert(u->set_rx_center_freq(2450000000ULL, &tr));
220    assert(u->set_rx_decim(DECIMATION));
221// rate = u->adc_rate()/u->decim():
222// u->set_sample_rate(rate);
223
224    u->adc_rate(&rate);
225
226    in = (fftw_complex *) fftw_malloc(sizeof(fftw_complex)*N);
227    out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex)*N);
228    plan = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
229
230    make_window();
231
232    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
233        fprintf(stderr, "SDL_init: %s\n", SDL_GetError());
234        exit(1);
235    }
236    atexit(SDL_Quit);
237
238    surf = SDL_SetVideoMode(XRES, YRES, 0, SDL_SWSURFACE);
239    if (!surf) {
240        fprintf(stderr, "SDL_SetVideoMode: %s\n", SDL_GetError());
241        exit(1);
242    }
243
244    assert(u->start_rx_streaming(0));
245    while (1||(!handler->has_errored_p() && !handler->has_finished_p())) {
246// while (!handler->has_finished_p()) {
247        SDL_Event event;
248
249        if (SDL_PollEvent(&event)) {
250            if (event.type == SDL_KEYDOWN)
251                if (key(event.key.keysym.sym))
252                    break;
253        }
254        assert(u->rx_samples(0, handler.get()));
255        u->rx_samples(0, handler.get());
256    }
257    u->stop_rx_streaming(0);
258    return 0;
259}
260

Archive Download this file

Branches:
master



interactive