ref: 11bee08c7da60c752092e5ada1ede8a9dc916a68
dir: /fs.h/
enum {
	Vsilent,
	Vstarting,
	Vplaying,
	Maxvoice = 16,
};
typedef struct Aux Aux;
typedef struct Auxdsp Auxdsp;
typedef struct Fs Fs;
typedef struct State State;
typedef struct Voice Voice;
typedef enum {
	Xclone,
	Xctl,
	Xmetadata,
	Xdsp,
	Xdspctl,
	Xdspdata,
	Xui,
	Xuictl,
	Xuimeta,
}Auxtype;
struct UI;
struct Aux {
	Auxtype type;
	int id;
	int ctl;
	int data;
	int metadata;
	int numin;
	int numout;
	int rate;
	int numvoices;
	struct UI *ui;
	State *state;
};
struct Fs {
	Srv srv;
	char *metadata;
	struct {
		Auxdsp *(*new)(int *numin, int *numout, int *rate);
		void (*free)(Auxdsp *dsp);
		void (*reset)(Auxdsp *dsp);
		/* optional, atm this one is needed only for autovoicing to work */
		Auxdsp *(*clone)(Auxdsp *dsp);
		/* optional, for autovoicing. this is ugly */
		void *(*state)(Auxdsp *dsp, int *sz);
		/* optional, n is always modulo number of channels */
		int (*read)(Auxdsp *dsp, float *b, int n);
		/* optional, n is always modulo number of channels */
		int (*write)(Auxdsp *dsp, float *b, int n);
	}dsp;
};
struct Voice {
	uvlong samples;
	Auxdsp *dsp;
	int state;
	int nzero;
};
struct State {
	float *mixer;
	int mixersz;
	Voice voice[Maxvoice];
	int crossvoice; /* copied from metadata on ctl write (gate) */
};
void fsinit(void *fs);