aboutsummaryrefslogtreecommitdiff
path: root/spectrogram.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectrogram.c')
-rw-r--r--spectrogram.c342
1 files changed, 11 insertions, 331 deletions
diff --git a/spectrogram.c b/spectrogram.c
index 96683a1..08ddb5d 100644
--- a/spectrogram.c
+++ b/spectrogram.c
@@ -17,117 +17,22 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <assert.h>
#include <err.h>
-#include <math.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
#include "aux.h"
#include "cms.h"
#include "fft.h"
#include "sio.h"
-
-#define HGAP 4
-#define VGAP 1
+#include "widget.h"
extern char *__progname;
int die = 0;
-struct pixmap {
- Pixmap pix;
- GC gc;
-};
-
-struct background {
- Pixmap pix;
- Pixmap mask;
- GC gc;
- XRectangle geo;
-};
-
-struct subwin {
- Window win;
- Pixmap pix; /* buffer */
- GC gc;
- XRectangle geo;
-};
-
-struct panel {
- Window win; /* container */
- struct subwin *wf;
- struct subwin *sp;
- struct background *bg;
- struct background *shadow;
- int mirror;
- int maxval;
- double *data;
- unsigned long *palette;
-};
-
-struct hsl {
- float h, s, l;
-};
-
-struct palette {
- struct hsl from, to;
-};
-
-enum mirror { LTR, RTL };
-
-struct palette p_spectr = {{ 120.0, 100.0, 75.0 }, { 0.0, 100.0, 25.0 }};
-struct palette p_shadow = {{ 120.0, 100.0, 10.0 }, { 0.0, 100.0, 10.0 }};
-struct palette p_waterfall = {{ 210.0, 75.0, 0.0 }, { 180.0, 100.0, 100.0 }};
-struct hsl hsl_gray = {0.0, 0.0, 20.0};
-
-unsigned long
-hslcolor(Display *d, struct hsl hsl)
-{
- int scr = DefaultScreen(d);
- Colormap cmap = DefaultColormap(d, scr);
- XColor c;
-
- hsl2rgb(&c.red, &c.green, &c.blue, hsl.h, hsl.s, hsl.l);
- c.flags = DoRed|DoGreen|DoBlue;
-
- XAllocColor(d, cmap, &c);
-
- return c.pixel;
-}
-
-unsigned long *
-init_palette(Display *d, struct palette pal, int n)
-{
- unsigned long *p;
- float hstep, sstep, lstep;
- int i;
-
- p = calloc(n, sizeof(unsigned long));
- assert(p);
-
- hstep = (pal.to.h - pal.from.h) / (n - 1);
- sstep = (pal.to.s - pal.from.s) / (n - 1);
- lstep = (pal.to.l - pal.from.l) / (n - 1);
-
- for (i = 0; i < n; i++) {
- p[i] = hslcolor(d, pal.from);
- pal.from.h += hstep;
- pal.from.s += sstep;
- pal.from.l += lstep;
- }
-
- return p;
-}
-
void
catch(int notused)
{
@@ -148,234 +53,6 @@ usage(void)
exit(0);
}
-void
-blit(Display *d, Drawable p, GC gc, XRectangle r)
-{
- XCopyArea(d, p, p, gc, 0, 0, r.width, r.height - 1, 0, 1);
-}
-
-void
-clear(Display *d, Drawable p, GC gc, XRectangle r)
-{
- XSetForeground(d, gc, BlackPixel(d, DefaultScreen(d)));
- XFillRectangle(d, p, gc, 0, 0, r.width, r.height);
-}
-
-void
-copy(Display *d, Drawable from, Drawable to, GC gc, XRectangle r, Drawable mask)
-{
- XSetClipMask(d, gc, mask);
- XCopyArea(d, from, to, gc, 0, 0, r.width, r.height, 0, 0);
- XSetClipMask(d, gc, None);
-}
-
-void
-draw_panel(Display *d, struct panel *p)
-{
- int i, v, x;
-
- /* blit waterfall */
- blit(d, p->wf->pix, p->wf->gc, p->wf->geo);
- /* blit shadow mask */
- blit(d, p->shadow->mask, p->shadow->gc, p->shadow->geo);
-
- /* clear spectrogram */
- clear(d, p->sp->pix, p->sp->gc, p->sp->geo);
- /* clear mask */
- clear(d, p->bg->mask, p->bg->gc, p->bg->geo);
-
- for (i = 0; i < p->sp->geo.width; i++) {
- /* limit maxval */
- v = p->data[i] >= p->maxval ? p->maxval - 1 : p->data[i];
- x = p->mirror ? p->sp->geo.width - i - 1 : i;
-
- /* draw waterfall */
- XSetForeground(d, p->wf->gc, p->palette[v]);
- XDrawPoint(d, p->wf->pix, p->wf->gc, x, 0);
-
- /* draw spectrogram */
- XSetForeground(d, p->bg->gc, 1);
- XDrawLine(d, p->bg->mask, p->bg->gc,
- x, p->bg->geo.height - v,
- x, p->bg->geo.height);
- }
-
- /* copy mask to shadow mask */
- copy(d, p->bg->mask, p->shadow->mask, p->shadow->gc, p->shadow->geo,
- p->bg->mask);
- /* shadow to buffer */
- copy(d, p->shadow->pix, p->sp->pix, p->sp->gc, p->sp->geo,
- p->shadow->mask);
- /* spectrogram to buffer */
- copy(d, p->bg->pix, p->sp->pix, p->sp->gc, p->sp->geo,
- p->bg->mask);
-}
-
-void
-flip(Display *d, struct subwin *p)
-{
- XCopyArea(d, p->pix, p->win, p->gc,
- 0, 0, p->geo.width, p->geo.height, 0, 0);
-}
-
-void
-flip_panel(Display *d, struct panel *p)
-{
- /* flip spectrogram */
- flip(d, p->sp);
- /* flip waterfall */
- flip(d, p->wf);
-}
-
-void
-draw_background(Display *d, Pixmap pix, GC gc, XRectangle r, unsigned long *pal)
-{
- int i, x, y;
-
- x = r.width - 1;
- for (i = 0; i < r.height; i++) {
- y = r.height - i - 1;
- XSetForeground(d, gc, pal[i]);
- XDrawLine(d, pix, gc, 0, y, x, y);
- }
-}
-
-struct background *
-init_background(Display *d, Drawable parent, XRectangle r)
-{
- struct background *p;
- int scr = DefaultScreen(d);
- int planes = DisplayPlanes(d, scr);
- int black = BlackPixel(d, scr);
-
- p = malloc(sizeof(struct subwin));
- assert(p);
-
- p->pix = XCreatePixmap(d, parent, r.width, r.height, planes);
- p->mask = XCreatePixmap(d, parent, r.width, r.height, 1);
- p->gc = XCreateGC(d, p->mask, 0, NULL);
- p->geo = r;
-
- /* clear */
- XSetForeground(d, p->gc, black);
- XFillRectangle(d, p->mask, p->gc, 0, 0, r.width, r.height);
-
- return p;
-}
-
-struct subwin *
-init_subwin(Display *d, Drawable parent, XRectangle r)
-{
- struct subwin *p;
- int scr = DefaultScreen(d);
- int white = WhitePixel(d, scr);
- int black = BlackPixel(d, scr);
- int planes = DisplayPlanes(d, scr);
-
- p = malloc(sizeof(struct subwin));
- assert(p);
-
- p->win = XCreateSimpleWindow(d, parent, r.x, r.y,
- r.width, r.height, 0, white, black);
- p->pix = XCreatePixmap(d, p->win, r.width, r.height, planes);
- p->gc = XCreateGC(d, p->pix, 0, NULL);
- p->geo = r;
-
- /* clear */
- XSetForeground(d, p->gc, black);
- XFillRectangle(d, p->pix, p->gc, 0, 0, r.width, r.height);
-
- XMapWindow(d, p->win);
-
- return p;
-}
-
-struct panel *
-init_panel(Display *d, Window win, XRectangle r, enum mirror m)
-{
- struct panel *p;
- int scr = DefaultScreen(d);
- unsigned long white = WhitePixel(d, scr);
- unsigned long gray = hslcolor(d, hsl_gray);
- unsigned long *palette;
- unsigned int maxval = r.height / 4;
- XRectangle geo;
-
- p = malloc(sizeof(struct panel));
- assert(p);
-
- p->data = calloc(2 * r.width, sizeof(double));
- assert(p->data);
-
- /* main panel window */
- p->win = XCreateSimpleWindow(d, win,
- r.x, r.y, r.width, r.height,
- 0, white, gray);
-
- /* sperctrogram window and its bitmasks */
- geo.x = 0;
- geo.y = 0;
- geo.width = r.width;
- geo.height = maxval;
- p->sp = init_subwin(d, p->win, geo);
-
- p->bg = init_background(d, p->sp->win, geo);
- palette = init_palette(d, p_spectr, maxval);
- draw_background(d, p->bg->pix, p->sp->gc, p->bg->geo, palette);
- free(palette);
-
- p->shadow = init_background(d, p->sp->win, geo);
- palette = init_palette(d, p_shadow, maxval);
- draw_background(d, p->shadow->pix, p->sp->gc, p->shadow->geo, palette);
- free(palette);
-
- p->palette = init_palette(d, p_waterfall, maxval);
- p->maxval = maxval;
- p->mirror = m;
-
- /* waterfall window and double buffer */
- geo.x = 0;
- geo.y = p->sp->geo.height + VGAP;
- geo.width = r.width;
- geo.height = r.height - maxval;
- p->wf = init_subwin(d, p->win, geo);
-
- XMapWindow(d, p->win);
-
- return p;
-}
-
-void
-free_background(Display *d, struct background *p)
-{
- XFreePixmap(d, p->pix);
- XFreePixmap(d, p->mask);
- XFreeGC(d, p->gc);
-}
-
-void
-free_subwin(Display *d, struct subwin *p)
-{
- XFreePixmap(d, p->pix);
- XFreeGC(d, p->gc);
- XUnmapWindow(d, p->win);
- XDestroyWindow(d, p->win);
-}
-
-void
-free_panel(Display *d, struct panel *p)
-{
- free_background(d, p->bg);
- free_background(d, p->shadow);
- free_subwin(d, p->sp);
- free_subwin(d, p->wf);
- XUnmapWindow(d, p->win);
- XDestroyWindow(d, p->win);
- free(p->palette);
- free(p->data);
- free(p);
-}
-
int
main(int argc, char **argv)
{
@@ -390,6 +67,7 @@ main(int argc, char **argv)
int scr;
struct panel *left, *right;
+ double *ldata, *rdata;
int dflag = 0; /* daemonize */
int fflag = 0; /* fullscreen */
@@ -494,12 +172,14 @@ main(int argc, char **argv)
geo.width = round / 2;
geo.height = height;
left = init_panel(dsp, container, geo, RTL);
+ ldata = dataptr(left);
geo.x = round / 2 + HGAP;
geo.y = 0;
geo.width = round / 2;
geo.height = height;
right = init_panel(dsp, container, geo, LTR);
+ rdata = dataptr(right);
XClearWindow(dsp, win);
XMapRaised(dsp, win); /* XMapWindow */
@@ -523,14 +203,14 @@ main(int argc, char **argv)
die = 1;
break;
case XK_1:
- left->mirror ^= 1;
+ toggle_mirror(left);
break;
case XK_2:
- right->mirror ^= 1;
+ toggle_mirror(right);
break;
case XK_3:
- left->mirror ^= 1;
- right->mirror ^= 1;
+ toggle_mirror(left);
+ toggle_mirror(right);
break;
default:
break;
@@ -547,10 +227,10 @@ main(int argc, char **argv)
}
}
- read_sio(left->data, right->data, round);
+ read_sio(ldata, rdata, round);
- exec_fft(left->data);
- exec_fft(right->data);
+ exec_fft(ldata);
+ exec_fft(rdata);
draw_panel(dsp, left);
draw_panel(dsp, right);