Commit b168a283 authored by Cedric Roux's avatar Cedric Roux

prepare code to handle more than one plot per plot

- array of plots
- deal with colors
parent fa49fe67
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
#define PLOT_VS_TIME 0 #define PLOT_VS_TIME 0
#define PLOT_IQ_POINTS 1 #define PLOT_IQ_POINTS 1
void *make_plot(int width, int height, int bufsize, char *title, int type); /* ... is { int count; int type; char *color; } for 'nplots' plots */
void plot_set(void *plot, float *data, int len, int pos); void *make_plot(int width, int height, char *title, int nplots, ...);
void iq_plot_set(void *plot, short *data, int len, int pos); void plot_set(void *plot, float *data, int len, int pos, int pp);
void iq_plot_set_sized(void *_plot, short *data, int len); void iq_plot_set(void *plot, short *data, int len, int pos, int pp);
void iq_plot_add_point_loop(void *_plot, short i, short q); void iq_plot_set_sized(void *_plot, short *data, int len, int pp);
void iq_plot_add_point_loop(void *_plot, short i, short q, int pp);
/* returns an opaque pointer - truly a 'database *', see t_data.c */ /* returns an opaque pointer - truly a 'database *', see t_data.c */
void *parse_database(char *filename); void *parse_database(char *filename);
......
...@@ -218,7 +218,7 @@ void get_message(int s) ...@@ -218,7 +218,7 @@ void get_message(int s)
#endif #endif
if (size != 4 * 7680) if (size != 4 * 7680)
{printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();} {printf("bad T_ENB_INPUT_SIGNAL, only 7680 samples allowed\n");abort();}
if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680); if (ul_plot) iq_plot_set(ul_plot, (short*)buf, 7680, subframe*7680, 0);
break; break;
} }
case T_ENB_UL_CHANNEL_ESTIMATE: { case T_ENB_UL_CHANNEL_ESTIMATE: {
...@@ -235,7 +235,7 @@ void get_message(int s) ...@@ -235,7 +235,7 @@ void get_message(int s)
if (size != 512*4) if (size != 512*4)
{printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n"); {printf("bad T_ENB_UL_CHANNEL_ESTIMATE, only 512 samples allowed\n");
abort();} abort();}
if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0); if (chest_plot) iq_plot_set(chest_plot, (short*)buf, 512, 0, 0);
break; break;
} }
case T_PUSCH_IQ: { case T_PUSCH_IQ: {
...@@ -260,7 +260,7 @@ void get_message(int s) ...@@ -260,7 +260,7 @@ void get_message(int s)
src = (uint32_t*)buf + l * 12 * 25; src = (uint32_t*)buf + l * 12 * 25;
for (i = 0; i < nb_rb*12; i++) *dst++ = *src++; for (i = 0; i < nb_rb*12; i++) *dst++ = *src++;
} }
iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14); iq_plot_set_sized(pusch_iq_plot, (short*)buf, nb_rb*12*14, 0);
} }
break; break;
} }
...@@ -273,7 +273,7 @@ void get_message(int s) ...@@ -273,7 +273,7 @@ void get_message(int s)
GET(s, &I, sizeof(int)); GET(s, &I, sizeof(int));
GET(s, &Q, sizeof(int)); GET(s, &Q, sizeof(int));
printf("receiving %d %d\n", I, Q); printf("receiving %d %d\n", I, Q);
if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10); if (pucch_iq_plot) iq_plot_add_point_loop(pucch_iq_plot, I*10, Q*10, 0);
break; break;
} }
case T_buf_test: { case T_buf_test: {
...@@ -385,11 +385,14 @@ int main(int n, char **v) ...@@ -385,11 +385,14 @@ int main(int n, char **v)
if (do_dump_database) { dump_database(database); return 0; } if (do_dump_database) { dump_database(database); return 0; }
if (do_xforms) { if (do_xforms) {
ul_plot = make_plot(512, 100, 7680*10, "UL Input Signal", PLOT_VS_TIME); ul_plot = make_plot(512, 100, "UL Input Signal", 1,
chest_plot = make_plot(512, 100, 512, "UL Channel Estimate UE 0", 7680*10, PLOT_VS_TIME, "blue");
PLOT_VS_TIME); chest_plot = make_plot(512, 100, "UL Channel Estimate UE 0", 1,
pusch_iq_plot = make_plot(100, 100, 12*25*14, "PUSCH IQ",PLOT_IQ_POINTS); 512, PLOT_VS_TIME, "blue");
pucch_iq_plot = make_plot(100, 100, 1000, "PUCCH IQ", PLOT_IQ_POINTS); pusch_iq_plot = make_plot(100, 100, "PUSCH IQ", 1,
12*25*14, PLOT_IQ_POINTS, "blue");
pucch_iq_plot = make_plot(100, 100, "PUCCH IQ", 1,
1000, PLOT_IQ_POINTS, "blue");
} }
for (i = 0; i < on_off_n; i++) for (i = 0; i < on_off_n; i++)
......
...@@ -8,22 +8,30 @@ ...@@ -8,22 +8,30 @@
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <sys/select.h> #include <sys/select.h>
#include <stdarg.h>
typedef struct { typedef struct {
Display *d;
Window w;
Pixmap p;
int width;
int height;
float *buf; float *buf;
short *iqbuf; short *iqbuf;
int count; int count;
int type; int type;
volatile int iq_count; /* for ULSCH IQ data */ volatile int iq_count; /* for ULSCH IQ data */
int iq_insert_pos; int iq_insert_pos;
GC g;
} data;
typedef struct {
Display *d;
Window w;
Pixmap px;
GC bg;
int width;
int height;
pthread_mutex_t lock; pthread_mutex_t lock;
float zoom; float zoom;
int timer_pipe[2]; int timer_pipe[2];
data *p; /* list of plots */
int nplots;
} plot; } plot;
static void *timer_thread(void *_p) static void *timer_thread(void *_p)
...@@ -52,6 +60,7 @@ static void *plot_thread(void *_p) ...@@ -52,6 +60,7 @@ static void *plot_thread(void *_p)
fd_set rset; fd_set rset;
int xfd = ConnectionNumber(p->d); int xfd = ConnectionNumber(p->d);
int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0]; int maxfd = xfd > p->timer_pipe[0] ? xfd : p->timer_pipe[0];
int pp;
while (1) { while (1) {
while (XPending(p->d)) { while (XPending(p->d)) {
...@@ -73,41 +82,31 @@ static void *plot_thread(void *_p) ...@@ -73,41 +82,31 @@ static void *plot_thread(void *_p)
replot = 0; replot = 0;
redraw = 1; redraw = 1;
/* TODO: get white & black GCs at startup */
{
GC gc;
XGCValues v;
gc = DefaultGC(p->d, DefaultScreen(p->d));
v.foreground = WhitePixel(p->d, DefaultScreen(p->d));
XChangeGC(p->d, gc, GCForeground, &v);
XFillRectangle(p->d, p->p, gc, 0, 0, p->width, p->height);
v.foreground = BlackPixel(p->d, DefaultScreen(p->d));
XChangeGC(p->d, gc, GCForeground, &v);
}
if (pthread_mutex_lock(&p->lock)) abort(); if (pthread_mutex_lock(&p->lock)) abort();
if (p->type == PLOT_VS_TIME) { for (pp = 0; pp < p->nplots; pp++) {
for (i = 0; i < p->count; i++) XFillRectangle(p->d, p->px, p->bg, 0, 0, p->width, p->height);
p->buf[i] = 10*log10(1.0+(float)(p->iqbuf[2*i]*p->iqbuf[2*i]+ if (p->p[pp].type == PLOT_VS_TIME) {
p->iqbuf[2*i+1]*p->iqbuf[2*i+1])); for (i = 0; i < p->p[pp].count; i++)
s = p->buf; p->p[pp].buf[i] =
10*log10(1.0+(float)(p->p[pp].iqbuf[2*i]*p->p[pp].iqbuf[2*i]+
p->p[pp].iqbuf[2*i+1]*p->p[pp].iqbuf[2*i+1]));
s = p->p[pp].buf;
for (i = 0; i < 512; i++) { for (i = 0; i < 512; i++) {
v = 0; v = 0;
for (j = 0; j < p->count/512; j++, s++) v += *s; for (j = 0; j < p->p[pp].count/512; j++, s++) v += *s;
v /= p->count/512; v /= p->p[pp].count/512;
XDrawLine(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)), XDrawLine(p->d, p->px, p->p[pp].g, i, 100, i, 100-v);
i, 100, i, 100-v);
} }
} else if (p->type == PLOT_IQ_POINTS) { } else if (p->p[pp].type == PLOT_IQ_POINTS) {
XPoint pts[p->iq_count]; XPoint pts[p->p[pp].iq_count];
int count = p->iq_count; int count = p->p[pp].iq_count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
pts[i].x = p->iqbuf[2*i]*p->zoom/20+50; pts[i].x = p->p[pp].iqbuf[2*i]*p->zoom/20+50;
pts[i].y = -p->iqbuf[2*i+1]*p->zoom/20+50; pts[i].y = -p->p[pp].iqbuf[2*i+1]*p->zoom/20+50;
}
XDrawPoints(p->d, p->px, p->p[pp].g, pts, count, CoordModeOrigin);
} }
XDrawPoints(p->d, p->p, DefaultGC(p->d, DefaultScreen(p->d)),
pts, count, CoordModeOrigin);
} }
if (pthread_mutex_unlock(&p->lock)) abort(); if (pthread_mutex_unlock(&p->lock)) abort();
...@@ -115,7 +114,7 @@ static void *plot_thread(void *_p) ...@@ -115,7 +114,7 @@ static void *plot_thread(void *_p)
if (redraw) { if (redraw) {
redraw = 0; redraw = 0;
XCopyArea(p->d, p->p, p->w, DefaultGC(p->d, DefaultScreen(p->d)), XCopyArea(p->d, p->px, p->w, DefaultGC(p->d, DefaultScreen(p->d)),
0, 0, p->width, p->height, 0, 0); 0, 0, p->width, p->height, 0, 0);
} }
...@@ -125,7 +124,7 @@ static void *plot_thread(void *_p) ...@@ -125,7 +124,7 @@ static void *plot_thread(void *_p)
if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort(); if (select(maxfd+1, &rset, NULL, NULL, NULL) == -1) abort();
if (FD_ISSET(p->timer_pipe[0], &rset)) { if (FD_ISSET(p->timer_pipe[0], &rset)) {
char b[512]; char b[512];
read(p->timer_pipe[0], b, 512); if (read(p->timer_pipe[0], b, 512) <= 0) abort();
replot = 1; replot = 1;
} }
} }
...@@ -150,12 +149,17 @@ static void new_thread(void *(*f)(void *), void *data) ...@@ -150,12 +149,17 @@ static void new_thread(void *(*f)(void *), void *data)
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); } { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
} }
void *make_plot(int width, int height, int count, char *title, int type) void *make_plot(int width, int height, char *title, int nplots, ...)
{ {
plot *p; plot *p;
Display *d; Display *d;
Window w; Window w;
Pixmap pm; Pixmap pm;
int i;
va_list ap;
XGCValues gcv;
p = malloc(sizeof(*p)); if (p == NULL) abort();
d = XOpenDisplay(0); if (d == NULL) abort(); d = XOpenDisplay(0); if (d == NULL) abort();
w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height, w = XCreateSimpleWindow(d, DefaultRootWindow(d), 0, 0, width, height,
...@@ -163,31 +167,70 @@ void *make_plot(int width, int height, int count, char *title, int type) ...@@ -163,31 +167,70 @@ void *make_plot(int width, int height, int count, char *title, int type)
XSelectInput(d, w, ExposureMask | ButtonPressMask); XSelectInput(d, w, ExposureMask | ButtonPressMask);
XMapWindow(d, w); XMapWindow(d, w);
{
XSetWindowAttributes att;
att.backing_store = Always;
XChangeWindowAttributes(d, w, CWBackingStore, &att);
}
XStoreName(d, w, title); XStoreName(d, w, title);
p->bg = XCreateGC(d, w, 0, NULL);
XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->bg);
gcv.foreground = WhitePixel(d, DefaultScreen(d));
XChangeGC(d, p->bg, GCForeground, &gcv);
pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d))); pm = XCreatePixmap(d, w, width, height, DefaultDepth(d, DefaultScreen(d)));
p = malloc(sizeof(*p)); if (p == NULL) abort();
p->width = width; p->width = width;
p->height = height; p->height = height;
p->p = malloc(nplots * sizeof(data)); if (p->p == NULL) abort();
va_start(ap, nplots);
for (i = 0; i < nplots; i++) {
int count;
int type;
char *color;
XColor rcol, scol;
count = va_arg(ap, int);
type = va_arg(ap, int);
color = va_arg(ap, char *);
p->p[i].g = XCreateGC(d, w, 0, NULL);
XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, p->p[i].g);
if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)),
color, &scol, &rcol)) {
gcv.foreground = scol.pixel;
XChangeGC(d, p->p[i].g, GCForeground, &gcv);
} else {
printf("could not allocate color '%s'\n", color);
abort();
}
if (type == PLOT_VS_TIME) { if (type == PLOT_VS_TIME) {
p->buf = malloc(sizeof(float) * count); if (p->buf == NULL) abort(); p->p[i].buf = malloc(sizeof(float) * count);
p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); if (p->p[i].buf == NULL) abort();
p->p[i].iqbuf = malloc(sizeof(short) * count * 2);
if(p->p[i].iqbuf==NULL)abort();
} else { } else {
p->buf = NULL; p->p[i].buf = NULL;
p->iqbuf = malloc(sizeof(short) * count * 2); if(p->iqbuf==NULL)abort(); p->p[i].iqbuf = malloc(sizeof(short) * count * 2);
if(p->p[i].iqbuf==NULL)abort();
}
p->p[i].count = count;
p->p[i].type = type;
p->p[i].iq_count = 0;
p->p[i].iq_insert_pos = 0;
} }
p->count = count; va_end(ap);
p->d = d; p->d = d;
p->w = w; p->w = w;
p->p = pm; p->px = pm;
p->type = type;
p->iq_count = 0;
p->iq_insert_pos = 0;
p->zoom = 1; p->zoom = 1;
p->nplots = nplots;
pthread_mutex_init(&p->lock, NULL); pthread_mutex_init(&p->lock, NULL);
...@@ -199,39 +242,39 @@ void *make_plot(int width, int height, int count, char *title, int type) ...@@ -199,39 +242,39 @@ void *make_plot(int width, int height, int count, char *title, int type)
return p; return p;
} }
void plot_set(void *_plot, float *data, int len, int pos) void plot_set(void *_plot, float *data, int len, int pos, int pp)
{ {
plot *p = _plot; plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort(); if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->buf + pos, data, len * sizeof(float)); memcpy(p->p[pp].buf + pos, data, len * sizeof(float));
if (pthread_mutex_unlock(&p->lock)) abort(); if (pthread_mutex_unlock(&p->lock)) abort();
} }
void iq_plot_set(void *_plot, short *data, int count, int pos) void iq_plot_set(void *_plot, short *data, int count, int pos, int pp)
{ {
plot *p = _plot; plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort(); if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->iqbuf + pos * 2, data, count * 2 * sizeof(short)); memcpy(p->p[pp].iqbuf + pos * 2, data, count * 2 * sizeof(short));
if (pthread_mutex_unlock(&p->lock)) abort(); if (pthread_mutex_unlock(&p->lock)) abort();
} }
void iq_plot_set_sized(void *_plot, short *data, int count) void iq_plot_set_sized(void *_plot, short *data, int count, int pp)
{ {
plot *p = _plot; plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort(); if (pthread_mutex_lock(&p->lock)) abort();
memcpy(p->iqbuf, data, count * 2 * sizeof(short)); memcpy(p->p[pp].iqbuf, data, count * 2 * sizeof(short));
p->iq_count = count; p->p[pp].iq_count = count;
if (pthread_mutex_unlock(&p->lock)) abort(); if (pthread_mutex_unlock(&p->lock)) abort();
} }
void iq_plot_add_point_loop(void *_plot, short i, short q) void iq_plot_add_point_loop(void *_plot, short i, short q, int pp)
{ {
plot *p = _plot; plot *p = _plot;
if (pthread_mutex_lock(&p->lock)) abort(); if (pthread_mutex_lock(&p->lock)) abort();
p->iqbuf[p->iq_insert_pos*2] = i; p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2] = i;
p->iqbuf[p->iq_insert_pos*2+1] = q; p->p[pp].iqbuf[p->p[pp].iq_insert_pos*2+1] = q;
if (p->iq_count != p->count) p->iq_count++; if (p->p[pp].iq_count != p->p[pp].count) p->p[pp].iq_count++;
p->iq_insert_pos++; p->p[pp].iq_insert_pos++;
if (p->iq_insert_pos == p->count) p->iq_insert_pos = 0; if (p->p[pp].iq_insert_pos == p->p[pp].count) p->p[pp].iq_insert_pos = 0;
if (pthread_mutex_unlock(&p->lock)) abort(); if (pthread_mutex_unlock(&p->lock)) abort();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment