ref: 663bc67e12efaccd4109068b05f8e6d671b7bd23
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 = RATE;
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, int *orate)
{
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);
*orate = rate;
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);
}