aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2011-03-12 01:53:00 +0000
committerDimitri Sokolyuk <demon@dim13.org>2011-03-12 01:53:00 +0000
commitfce59d949c0a4767009a9db94f0af0903ff31be1 (patch)
treebfcd4b47fa07cc29e6256f3fbda802901215ec0c
sio spectrogram
-rw-r--r--Makefile22
-rw-r--r--fft.c58
-rw-r--r--fft.h26
-rw-r--r--fifo.c101
-rw-r--r--fifo.h27
-rw-r--r--hsv2rgb.c96
-rw-r--r--hsv2rgb.h23
-rw-r--r--spectrogram.c438
8 files changed, 791 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..e053cc7
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+# $Id$
+
+PROG= spectrogram
+SRCS= spectrogram.c fifo.c fft.c hsv2rgb.c
+HEADERS=fifo.h fft.h hsv2rgb.h
+CFLAGS+=-I/usr/local/include \
+ -I/usr/local/include/SDL \
+ -D_GNU_SOURCE=1 \
+ -D_REENTRANT \
+ -I/usr/X11R6/include \
+ -DXTHREADS
+LDADD+= -L/usr/local/lib \
+ -lSDL \
+ -pthread \
+ -L/usr/X11R6/lib \
+ -R/usr/X11R6/lib
+LDADD+= -lsndio -lfftw3 -lm
+#LDADD+= -liconv -lusbhid -lX11 -lxcb -lXau -lXdmcp
+DEBUG+= -Wall
+#DEBUG+=-ggdb -g -pg
+
+.include <bsd.prog.mk>
diff --git a/fft.c b/fft.c
new file mode 100644
index 0000000..5372b89
--- /dev/null
+++ b/fft.c
@@ -0,0 +1,58 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <fftw3.h>
+
+struct fft {
+ fftw_plan plan;
+ double *in;
+ double *out;
+ int n;
+};
+
+struct fft *
+init_fft(int n)
+{
+ struct fft *p;
+
+ p = malloc(sizeof(struct fft));
+ p->in = fftw_malloc(n * sizeof(double));
+ p->out = fftw_malloc(n * sizeof(double));
+ p->plan = fftw_plan_r2r_1d(n, p->in, p->out, FFTW_R2HC, FFTW_MEASURE);
+ p->n = n;
+
+ return p;
+}
+
+int
+dofft(struct fft *p, double *data)
+{
+ int i, n;
+
+ memset(p->out, 0, p->n * sizeof(double));
+ memcpy(p->in, data, p->n * sizeof(double));
+ fftw_execute(p->plan);
+
+ n = p->n / 2;
+ for (i = 1; i < n; i++)
+ data[i - 1] = sqrt(i * (p->out[i] * p->out[i] + p->out[p->n - i] * p->out[p->n - i]));
+
+ return 0;
+}
diff --git a/fft.h b/fft.h
new file mode 100644
index 0000000..851045f
--- /dev/null
+++ b/fft.h
@@ -0,0 +1,26 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 __FFT_H
+#define __FFT_H
+
+struct fft;
+
+struct fft *init_fft(int);
+int dofft(struct fft *, double *);
+
+#endif
diff --git a/fifo.c b/fifo.c
new file mode 100644
index 0000000..5b80ec8
--- /dev/null
+++ b/fifo.c
@@ -0,0 +1,101 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct buf {
+ double *buf;
+ double *end;
+ double *wr;
+ double *rd;
+};
+
+struct fifo {
+ struct buf l;
+ struct buf r;
+ size_t sz;
+};
+
+struct fifo *
+init_fifo(int n)
+{
+ struct fifo *ff;
+
+ ff = malloc(sizeof(struct fifo));
+
+ ff->l.buf = malloc(n * sizeof(double));
+ ff->l.end = ff->l.buf + n;
+ ff->l.wr = ff->l.buf;
+ ff->l.rd = ff->l.buf;
+
+ ff->r.buf = malloc(n * sizeof(double));
+ ff->r.end = ff->r.buf + n;
+ ff->r.wr = ff->r.buf;
+ ff->r.rd = ff->r.buf;
+
+ ff->sz = 0;
+
+ return ff;
+}
+
+int
+wr_fifo(struct fifo *ff, double *l, double *r, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ *ff->l.wr++ = *l++;
+ *ff->r.wr++ = *r++;
+ if (ff->l.wr >= ff->l.end) {
+ ff->l.wr = ff->l.buf;
+ ff->r.wr = ff->r.buf;
+ }
+ }
+ ff->sz += n;
+
+ return ff->sz;
+}
+
+int
+rd_fifo(struct fifo *ff, double *l, double *r, int n, double *w)
+{
+ int i;
+ double *lnext = ff->l.rd;
+ double *rnext = ff->r.rd;
+
+ for (i = 0; i < n; i++) {
+ if (i == n / 4) {
+ lnext = ff->l.rd;
+ rnext = ff->r.rd;
+ }
+ *l++ = *ff->l.rd++ * w[i];
+ *r++ = *ff->r.rd++ * w[i];
+ if (ff->l.rd >= ff->l.end) {
+ ff->l.rd = ff->l.buf;
+ ff->r.rd = ff->r.buf;
+ }
+ }
+ ff->l.rd = lnext;
+ ff->r.rd = rnext;
+
+ ff->sz -= n / 4;
+
+ return ff->sz;
+}
diff --git a/fifo.h b/fifo.h
new file mode 100644
index 0000000..63b6899
--- /dev/null
+++ b/fifo.h
@@ -0,0 +1,27 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 __FIFO_H
+#define __FIFO_H
+
+struct fifo;
+
+struct fifo *init_fifo(size_t);
+int wr_fifo(struct fifo *, double *, double *, size_t);
+int rd_fifo(struct fifo *, double *, double *, size_t, double *);
+
+#endif
diff --git a/hsv2rgb.c b/hsv2rgb.c
new file mode 100644
index 0000000..6339533
--- /dev/null
+++ b/hsv2rgb.c
@@ -0,0 +1,96 @@
+/* $Id$ */
+/* hsv2rgb.c
+ * Convert Hue Saturation Value to Red Green Blue
+ *
+ * P.J. 08-Aug-98
+ *
+ * Reference:
+ * D. F. Rogers
+ * Procedural Elements for Computer Graphics
+ * McGraw Hill 1985
+ */
+
+#include <stdint.h>
+
+int
+hsv2rgb(uint8_t *r, uint8_t *g, uint8_t *b, float h, float s, float v)
+{
+ /*
+ * Purpose:
+ * Convert HSV values to RGB values
+ * All values are in the range [0.0 .. 1.0]
+ */
+ float F, M, N, K;
+ int i;
+
+ /* normalize */
+ if (s < 0.0) {
+ h += 0.5;
+ s = -s;
+ }
+
+ if (v < 0.0)
+ v = -v;
+
+ while (h > 1.0)
+ h -= 1.0;
+ while (h < 0.0)
+ h += 1.0;
+
+
+ if (s == 0.0) {
+ /*
+ * Achromatic case, set level of grey
+ */
+ *r = v * 255;
+ *g = v * 255;
+ *b = v * 255;
+ } else {
+ /*
+ * Determine levels of primary colours.
+ */
+
+ h = (h >= 1.0) ? 0.0 : h * 6;
+ i = (int)h; /* should be in the range 0..5 */
+ F = h - i; /* fractional part */
+
+ M = v * (1 - s);
+ N = v * (1 - s * F);
+ K = v * (1 - s * (1 - F));
+
+ switch (i) {
+ case 0:
+ *r = v * 255;
+ *g = K * 255;
+ *b = M * 255;
+ break;
+ case 1:
+ *r = N * 255;
+ *g = v * 255;
+ *b = M * 255;
+ break;
+ case 2:
+ *r = M * 255;
+ *g = v * 255;
+ *b = K * 255;
+ break;
+ case 3:
+ *r = M * 255;
+ *g = N * 255;
+ *b = v * 255;
+ break;
+ case 4:
+ *r = K * 255;
+ *g = M * 255;
+ *b = v * 255;
+ break;
+ case 5:
+ *r = v * 255;
+ *g = M * 255;
+ *b = N * 255;
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/hsv2rgb.h b/hsv2rgb.h
new file mode 100644
index 0000000..9851ca0
--- /dev/null
+++ b/hsv2rgb.h
@@ -0,0 +1,23 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 __HSV2RGB_H
+#define __HSV2RGB_H
+
+int hsv2rgb(uint8_t *r, uint8_t *g, uint8_t *b, float h, float s, float v);
+
+#endif
diff --git a/spectrogram.c b/spectrogram.c
new file mode 100644
index 0000000..063bbfb
--- /dev/null
+++ b/spectrogram.c
@@ -0,0 +1,438 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * 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 <sys/types.h>
+#include <sys/time.h>
+#include <err.h>
+#include <assert.h>
+#include <sndio.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <signal.h>
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+// #include <SDL/SDL_keysym.h>
+
+#include "fifo.h"
+#include "fft.h"
+#include "hsv2rgb.h"
+
+#define PSIZE 250
+#define SSIZE (PSIZE >> 1)
+
+#define TIMING 0
+
+struct buf {
+ int16_t left;
+ int16_t right;
+};
+
+SDL_Surface *screen;
+SDL_Color *pane;
+SDL_Color *pan2;
+SDL_Color black = { .r = 0, .g = 0, .b = 0 };
+SDL_Color white = { .r = 255, .g = 255, .b = 255 };
+
+SDL_Rect wf_from, wf_to;
+SDL_Rect wf_left, wf_right;
+SDL_Rect sp_left, sp_right;
+
+int die = 0;
+
+void
+init_rect(int w, int h, int off, int s)
+{
+ wf_from.x = off;
+ wf_from.y = 1;
+ wf_from.w = w - 2 * off;
+ wf_from.h = h - s - 1;
+
+ wf_to.x = off;
+ wf_to.y = 0;
+ wf_to.w = w - 2 * off;
+ wf_to.h = h - s - 1;
+
+ wf_left.x = off;
+ wf_left.y = h - s - 1;
+ wf_left.w = w / 2 - 2 * off;
+ wf_left.h = 1;
+
+ wf_right.x = w / 2 + off;
+ wf_right.y = h - s - 1;
+ wf_right.w = w / 2 - 2 * off;
+ wf_right.h = 1;
+
+ sp_left.x = off;
+ sp_left.y = h - s;
+ sp_left.w = w / 2 - 2 * off;
+ sp_left.h = s;
+
+ sp_right.x = w / 2 + off;
+ sp_right.y = h - s;
+ sp_right.w = w / 2 - 2 * off;
+ sp_right.h = s;
+}
+
+SDL_Color *
+init_palette_small(int n)
+{
+ SDL_Color *p;
+ int i;
+ float h, s, v;
+ float hstep, sstep, vstep;
+
+
+ p = malloc(n * sizeof(SDL_Color));
+
+ h = 0.3;
+ hstep = -0.3 / n;
+
+ s = 0.5;
+ sstep = 0.5 / n;
+
+ v = 0.75;
+ vstep = 0.25 / n;
+
+
+ for (i = 0; i < n; i++) {
+ hsv2rgb(&p[i].r, &p[i].g, &p[i].b, h, s, v);
+ h += hstep;
+ s += sstep;
+ v += vstep;
+ }
+
+ return p;
+}
+
+SDL_Color *
+init_palette_big(int n)
+{
+ SDL_Color *p;
+ int i;
+ float h, s, v;
+ float hstep, sstep, vstep;
+ float k;
+ int f = 100;
+
+ p = malloc(n * sizeof(SDL_Color));
+ k = 1.0 / logf(f + 1);
+
+ h = 0.65;
+ hstep = -0.4 / n;
+
+ s = 1.0;
+ sstep = -1.0 / n;
+
+ v = 0.0;
+ vstep = 1.0 / n;
+
+ for (i = 0; i < n; i++) {
+ hsv2rgb(&p[i].r, &p[i].g, &p[i].b, h, s,
+ k * logf(f * v + 1));
+ // hsv2rgb(&p[i].r, &p[i].g, &p[i].b, h, s, sqrtf(v));
+
+ h += hstep;
+ s += sstep;
+ v += vstep;
+ }
+
+ return p;
+}
+
+int *
+init_scala(int n, int w)
+{
+ int *s, i;
+ float k;
+
+ s = malloc(w * sizeof(int));
+
+ k = n / logf(w);
+
+ for (i = 0; i < w; i++)
+ s[i] = n - k * logf(w - i);
+
+ return s;
+}
+
+int *
+init_factor(int *scala, int w)
+{
+ int *s, k, i;
+
+ s = malloc(w * sizeof(int));
+ k = 0;
+ for (i = 0; i < w; i++) {
+ s[i] = scala[i] - k;
+ if (s[i] == 0)
+ s[i] = 1;
+ k = scala[i];
+ }
+
+ return s;
+}
+
+#if 1
+void inline
+drawpixel(SDL_Surface *s, int x, int y, SDL_Color *c)
+{
+ Uint32 *buf = (Uint32 *)s->pixels + y * (s->pitch >> 2) + x;
+ Uint32 pixel = SDL_MapRGB(s->format, c->r, c->g, c->b);
+ *buf = pixel;
+}
+#else
+#define drawpixel(s, x, y, c) do { \
+ Uint32 *buf, pixel; \
+ buf = (Uint32 *)(s)->pixels + (y) * ((s)->pitch >> 2) + (x); \
+ pixel = SDL_MapRGB((s)->format, (c)->r, (c)->g, (c)->b); \
+ *buf = pixel; \
+ } while (0)
+#endif
+
+int
+draw(double *left, double *right, int n, int *scala, int *fact, int p)
+{
+ int x, y, l, r, i;
+
+ if (SDL_MUSTLOCK(screen) && SDL_LockSurface(screen))
+ return -1;
+
+ SDL_BlitSurface(screen, &wf_from, screen, &wf_to);
+
+ for (x = 0; x < wf_left.w; x++) {
+ l = 0;
+ r = 0;
+
+ for (i = 0; i < fact[x]; i++) {
+ l += left[scala[x] - i] + 0.5;
+ r += right[scala[x] - i] + 0.5;
+ }
+
+ l /= fact[x];
+ r /= fact[x];
+
+ l >>= 1;
+ r >>= 1;
+
+ if (l >= p)
+ l = p - 1;
+ if (r >= p)
+ r = p - 1;
+
+ drawpixel(screen, wf_left.x + x, wf_left.y, &pane[l]);
+ drawpixel(screen, wf_right.x + x, wf_right.y, &pane[r]);
+
+ /* *** */
+
+ l >>= 1;
+ r >>= 1;
+
+ for (y = 0; y < sp_left.h; y++) {
+ drawpixel(screen, sp_left.x + x,
+ sp_left.y + sp_left.h - y - 1,
+ l > y ? &pan2[y] : &black);
+ drawpixel(screen, sp_right.x + x,
+ sp_right.y + sp_right.h - y - 1,
+ r > y ? &pan2[y] : &black);
+ }
+ }
+
+ if (SDL_MUSTLOCK(screen))
+ SDL_UnlockSurface(screen);
+
+ SDL_Flip(screen);
+
+ return 0;
+}
+
+double *
+init_wights(int n)
+{
+ double *w;
+ int i;
+
+ w = calloc(n, sizeof(double));
+ assert(w);
+
+ for (i = 0; i < n; i++)
+ w[i] = (1 - cos((2 * M_PI * i) / (n - 1))) / 2;
+
+ return w;
+}
+
+void
+catch(int notused)
+{
+ die = 1;
+}
+
+int
+main(int argc, char **argv)
+{
+ const SDL_VideoInfo *vi;
+ SDL_Event event;
+
+ struct buf *buf;
+ size_t bufsz;
+
+ struct sio_hdl *sio;
+ struct sio_par par;
+ struct fifo *ff;
+ struct fft *fft;
+
+ double *left, *right;
+ int c, i, n, k, r, delta;
+ double *wights;
+ int *scala;
+ int *factor;
+ int psize, ssize;
+ int height = 0;
+ int width = 0;
+ int sdlargs;
+
+
+ #if TIMING
+ struct timeval ta, te;
+ #endif
+
+ while ((c = getopt(argc, argv, "h:w:")) != -1)
+ switch (c) {
+ case 'h':
+ height = atoi(optarg);
+ break;
+ case 'w':
+ width = atoi(optarg);
+ break;
+ default:
+ break;
+ }
+
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ return 1;
+
+ signal(SIGINT, catch);
+ atexit(SDL_Quit);
+
+ vi = SDL_GetVideoInfo();
+ if (!vi)
+ return 1;
+ warnx("%dx%d", vi->current_w, vi->current_h);
+
+ sdlargs = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+ if (!height && !width)
+ sdlargs |= SDL_FULLSCREEN;
+ if (!height)
+ height = vi->current_h - 1;
+ if (!width)
+ width = vi->current_w - 1;
+
+ screen = SDL_SetVideoMode(width, height, 32, sdlargs);
+ if (!screen)
+ return 1;
+
+ SDL_ShowCursor(SDL_DISABLE);
+
+ psize = 2 * vi->current_h / 3;
+ ssize = psize >> 2;
+
+ init_rect(vi->current_w, vi->current_h, 1, ssize);
+
+ pan2 = init_palette_small(ssize);
+ pane = init_palette_big(psize);
+
+ sio = sio_open(NULL, SIO_REC, 0);
+ assert(sio);
+
+ sio_initpar(&par);
+ sio_getpar(sio, &par);
+
+ delta = par.round / 2;
+// delta = 1024; /* XXX */
+ n = 4 * delta;
+ warnx("delta: %d, n: %d", delta, n);
+
+ bufsz = delta * sizeof(struct buf);
+ buf = malloc(bufsz);
+ assert(buf);
+
+ left = calloc(n, sizeof(double));
+ right = calloc(n, sizeof(double));
+ assert(left && right);
+
+ sio_start(sio);
+
+ fft = init_fft(n);
+ wights = init_wights(n);
+ ff = init_fifo(10 * n);
+ scala = init_scala(n / 2, wf_left.w);
+ factor = init_factor(scala, wf_left.w);
+
+ #if TIMING
+ gettimeofday(&ta, NULL);
+ #endif
+
+ while (!die) {
+ k = sio_read(sio, buf, bufsz) / sizeof(struct buf);
+ for (i = 0; i < k; i++) {
+ left[i] = buf[i].left / (double)INT16_MAX;
+ right[i] = buf[i].right / (double)INT16_MAX;
+ }
+ r = wr_fifo(ff, left, right, k);
+
+ if (r >= n) {
+ rd_fifo(ff, left, right, n, wights);
+
+ dofft(fft, left);
+ dofft(fft, right);
+
+ draw(left, right, n / 2, scala, factor, psize);
+ }
+
+ SDL_PollEvent(&event);
+ switch (event.type) {
+ case SDL_QUIT:
+ die = 1;
+ break;
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == SDLK_q)
+ die = 1;
+ break;
+ }
+ #if TIMING
+ gettimeofday(&te, NULL);
+ fprintf(stderr, "%8d time elapsed: %7.6lf sec\r",
+ r, te.tv_sec - ta.tv_sec
+ + (te.tv_usec - ta.tv_usec)/1000000.0);
+ memcpy(&ta, &te, sizeof(struct timeval));
+ #endif
+ }
+
+
+ sio_stop(sio);
+ sio_close(sio);
+
+ free(left);
+ free(right);
+ free(buf);
+
+ return 0;
+}