From ce4c20d0acc9cec5551934131feae7ecd11ddedf Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 10 Sep 2014 21:21:43 +0000 Subject: split code --- Makefile | 2 +- cms.h | 10 ++ spectrogram.c | 342 ++-------------------------------------------------------- widget.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++++++++ widget.h | 71 ++++++++++++ 5 files changed, 403 insertions(+), 332 deletions(-) create mode 100644 widget.c create mode 100644 widget.h diff --git a/Makefile b/Makefile index 6f9ec6c..1380b09 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION=2.0 PROG= spectrogram -SRCS= spectrogram.c sio.c fft.c cms.c aux.c +SRCS= spectrogram.c sio.c fft.c cms.c aux.c widget.c BINDIR= /usr/local/bin HEADERS=sio.h fft.h cms.h aux.h LIBS= fftw3 x11 diff --git a/cms.h b/cms.h index 111b3ae..e98f576 100644 --- a/cms.h +++ b/cms.h @@ -18,6 +18,16 @@ #ifndef __CMS_H #define __CMS_H +/* +struct hsl { + double h, s, l; +}; + +struct palette { + struct hsl from, to; +}; + */ + __BEGIN_DECLS void hsv2rgb( unsigned short *r, unsigned short *g, unsigned short *b, diff --git a/spectrogram.c b/spectrogram.c index 96683a1..08ddb5d 100644 --- a/spectrogram.c +++ b/spectrogram.c @@ -17,117 +17,22 @@ #include #include -#include -#include -#include - -#include #include -#include #include -#include #include #include -#include #include #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); diff --git a/widget.c b/widget.c new file mode 100644 index 0000000..e0b9921 --- /dev/null +++ b/widget.c @@ -0,0 +1,310 @@ +/* $Id$ */ +/* + * Copyright (c) 2010 Dimitri Sokolyuk + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include + +#include "widget.h" +#include "cms.h" + +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; +} + + +static void +blit(Display *d, Drawable p, GC gc, XRectangle r) +{ + XCopyArea(d, p, p, gc, 0, 0, r.width, r.height - 1, 0, 1); +} + +static 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); +} + +static 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); +} + +static 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); +} + +static 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); + } +} + +static 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; +} + +static 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; +} + +static void +free_background(Display *d, struct background *p) +{ + XFreePixmap(d, p->pix); + XFreePixmap(d, p->mask); + XFreeGC(d, p->gc); +} + +static 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); +} + +void +toggle_mirror(struct panel *p) +{ + p->mirror ^= 1; +} + +double * +dataptr(struct panel *p) +{ + return p->data; +} diff --git a/widget.h b/widget.h new file mode 100644 index 0000000..002db22 --- /dev/null +++ b/widget.h @@ -0,0 +1,71 @@ +/* $Id$ */ +/* + * Copyright (c) 2010 Dimitri Sokolyuk + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _WIDGET_H +#define _WIDGET_H + +#define HGAP 4 +#define VGAP 1 + +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 }; + +__BEGIN_DECLS +unsigned long hslcolor(Display *, struct hsl); +unsigned long *init_palette(Display *, struct palette, int); +void draw_panel(Display *, struct panel *); +void flip_panel(Display *, struct panel *); +struct panel *init_panel(Display *, Window, XRectangle, enum mirror); +void free_panel(Display *, struct panel *); +void toggle_mirror(struct panel *); +double *dataptr(struct panel *); +__END_DECLS + +#endif -- cgit v1.2.3