ref: 75686444e07d768ce76c383ba434fdeb55c6c13d
dir: /dsp/main.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <thread.h> #include <9p.h> #include "uiglue.h" typedef struct DSP DSP; #include "dspf.h" #include "common.h" #include "fs.h" #include "ui.h" /* FIXME figure out how to get the buffering right */ enum { Inmax = 2048, /* float = 8192 bytes */ Outmax = 2048, /* float = 8192 bytes */ }; struct Auxdsp { void *dsp; float **in, **out; int numin, numout; int inmax, outmax; }; static int rate = 44100; static DSPf *dspf; static Auxdsp * dspwrap(void *p) { Auxdsp *dsp; int i; if ((dsp = calloc(1, sizeof(*dsp))) == nil) return nil; dsp->dsp = p; dsp->in = dsp->out = nil; if ((dsp->numin = dspf->num_in(dsp->dsp)) > 0) { dsp->in = malloc(sizeof(*dsp->in) * dsp->numin); dsp->inmax = Inmax; for (i = 0; i < dsp->numin; i++) dsp->in[i] = malloc(sizeof(**dsp->in) * dsp->inmax); } if ((dsp->numout = dspf->num_out(dsp->dsp)) > 0) { dsp->out = malloc(sizeof(*dsp->out) * dsp->numout); dsp->outmax = Outmax; for (i = 0; i < dsp->numout; i++) dsp->out[i] = malloc(sizeof(**dsp->out) * dsp->outmax); } return dsp; } static Auxdsp * dspnew(int *numin, int *numout) { Auxdsp *dsp; dsp = dspwrap(dspf->new()); dspf->init(dsp->dsp, rate); dspf->build_ui(dsp->dsp, &uiglue); *numin = dspf->num_in(dsp->dsp); *numout = dspf->num_out(dsp->dsp); return dsp; } static Auxdsp * dspclone(Auxdsp *dsp) { Auxdsp *clone; int i; clone = dspwrap(dspf->clone(dsp->dsp)); if (clone->in != nil) { /* copy input data */ /* FIXME need to set the valid data size when the processing is in */ for (i = 0; i < dsp->numin; i++) memmove(clone->in[i], dsp->in[i], sizeof(**dsp->in)*dsp->inmax); } return clone; } static void * dspstate(Auxdsp *dsp, int *sz) { return dspf->state(dsp->dsp, sz); } static void dspfree(Auxdsp *dsp) { int i; dspf->delete(dsp->dsp); for (i = 0; i < dsp->numin; i++) free(dsp->in[i]); free(dsp->in); for (i = 0; i < dsp->numout; i++) free(dsp->out[i]); free(dsp->out); free(dsp); } static void dspreset(Auxdsp *dsp) { dspf->reset_ui(dsp->dsp); } static int dspread(Auxdsp *dsp, float *b, int n) { int i, j, numframes; numframes = n / dsp->numout; dspf->compute(dsp->dsp, numframes, dsp->in, dsp->out); for (i = 0; i < numframes; i++) { for (j = 0; j < dsp->numout; j++) *b++ = dsp->out[j][i]; } return n; } static void usage(void) { print("usage: %s [-s srv] [-m mtpt] [-r rate]\n", argv0); exits("usage"); } static Fs fs = { .dsp = { .new = dspnew, .clone = dspclone, .state = dspstate, .free = dspfree, .reset = dspreset, .read = dspread, }, }; static void addmeta(void *metaInterface, const char *k, const char *v) { int klen, vlen; static int metalen; USED(metaInterface); if (strchr(k, '/') != nil) /* ignore library-specific meta */ return; klen = strlen(k); vlen = strlen(v); fs.metadata = realloc(fs.metadata, metalen + klen + 1 + vlen + 2); strcpy(fs.metadata+metalen, k); metalen += klen; fs.metadata[metalen++] = '\t'; strcpy(fs.metadata+metalen, v); metalen += vlen; fs.metadata[metalen++] = '\n'; fs.metadata[metalen] = 0; } void threadmain(int argc, char **argv) { char *srv, *mtpt; MetaGlue mg; srv = nil; mtpt = nil; ARGBEGIN{ case 'D': chatty9p++; break; case 's': srv = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; case 'r': rate = atoi(EARGF(usage())); break; default: usage(); }ARGEND if (srv == nil && mtpt == nil) sysfatal("must specify -s or -m option"); setfcr(FPPDBL|FPRNR); mg.declare = addmeta; dspf = class_init(rate); dspf->metadata(&mg); fsinit(&fs); threadpostmountsrv(&fs.srv, srv, mtpt, MREPL); threadexits(nil); }