2012-09-02 17:13:30 -05:00
|
|
|
/* $OpenBSD$ */
|
|
|
|
/*
|
2012-11-10 07:58:53 -06:00
|
|
|
* Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
|
2012-09-02 17:13:30 -05:00
|
|
|
*
|
|
|
|
* 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 DEV_H
|
|
|
|
#define DEV_H
|
|
|
|
|
|
|
|
#include "abuf.h"
|
|
|
|
#include "dsp.h"
|
2012-11-02 06:43:43 -05:00
|
|
|
#include "siofile.h"
|
2012-09-02 17:13:30 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* audio stream state structure
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct slotops
|
|
|
|
{
|
|
|
|
void (*onmove)(void *, int); /* clock tick */
|
|
|
|
void (*onvol)(void *, unsigned int); /* tell client vol changed */
|
|
|
|
void (*fill)(void *); /* request to fill a play block */
|
|
|
|
void (*flush)(void *); /* request to flush a rec block */
|
|
|
|
void (*eof)(void *); /* notify that play drained */
|
|
|
|
void (*mmcstart)(void *); /* request to start */
|
|
|
|
void (*mmcstop)(void *); /* request to stop */
|
|
|
|
void (*mmcloc)(void *, unsigned int); /* relocate to new position */
|
|
|
|
void (*exit)(void *); /* delete client */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct slot {
|
|
|
|
struct slotops *ops; /* client callbacks */
|
|
|
|
struct slot *next; /* next on the play list */
|
|
|
|
struct dev *dev; /* device this belongs to */
|
|
|
|
void *arg; /* user data for callbacks */
|
|
|
|
struct aparams par; /* socket side params */
|
|
|
|
struct {
|
|
|
|
int weight; /* dynamic range */
|
|
|
|
int maxweight; /* max dynamic range allowed */
|
|
|
|
unsigned int vol; /* volume within the vol */
|
|
|
|
int drop; /* to drop on next read */
|
|
|
|
struct abuf buf; /* socket side buffer */
|
2012-11-02 13:05:29 -05:00
|
|
|
int bpf; /* byte per frame */
|
2012-09-02 17:13:30 -05:00
|
|
|
int slot_cmin, slot_cmax; /* slot source chans */
|
|
|
|
int dev_cmin, dev_cmax; /* device destination chans */
|
|
|
|
struct cmap cmap; /* channel mapper state */
|
|
|
|
struct resamp resamp; /* resampler state */
|
|
|
|
struct conv dec; /* format decoder params */
|
2012-09-04 05:48:45 -05:00
|
|
|
int join; /* channel join factor */
|
|
|
|
int expand; /* channel expand factor */
|
|
|
|
void *resampbuf, *decbuf; /* tmp buffers */
|
2012-09-02 17:13:30 -05:00
|
|
|
} mix;
|
|
|
|
struct {
|
|
|
|
int silence; /* to add on next write */
|
|
|
|
struct abuf buf; /* socket side buffer */
|
2012-11-02 13:05:29 -05:00
|
|
|
int bpf; /* byte per frame */
|
2012-09-02 17:13:30 -05:00
|
|
|
int slot_cmin, slot_cmax; /* slot destination chans */
|
|
|
|
int dev_cmin, dev_cmax; /* device source chans */
|
|
|
|
struct cmap cmap; /* channel mapper state */
|
|
|
|
struct resamp resamp; /* buffer for resampling */
|
|
|
|
struct conv enc; /* buffer for encoding */
|
2012-09-04 05:48:45 -05:00
|
|
|
int join; /* channel join factor */
|
|
|
|
int expand; /* channel expand factor */
|
|
|
|
void *resampbuf, *encbuf; /* tmp buffers */
|
2012-09-02 17:13:30 -05:00
|
|
|
} sub;
|
|
|
|
int xrun; /* underrun policy */
|
|
|
|
int dup; /* mono-to-stereo and alike */
|
|
|
|
#define SLOT_BUFSZ(s) \
|
|
|
|
((s)->appbufsz + (s)->dev->bufsz / (s)->dev->round * (s)->round)
|
|
|
|
int appbufsz; /* slot-side buffer size */
|
|
|
|
int round; /* slot-side block size */
|
|
|
|
int rate; /* slot-side sample rate */
|
|
|
|
int delta; /* pending clock ticks */
|
|
|
|
int delta_rem; /* remainder for delta */
|
|
|
|
int mode; /* MODE_{PLAY,REC} */
|
|
|
|
#define SLOT_INIT 0 /* not trying to do anything */
|
|
|
|
#define SLOT_START 1 /* buffer allocated */
|
|
|
|
#define SLOT_READY 2 /* buffer filled enough */
|
|
|
|
#define SLOT_RUN 3 /* buffer attached to device */
|
|
|
|
#define SLOT_STOP 4 /* draining */
|
|
|
|
int pstate;
|
|
|
|
|
|
|
|
#define SLOT_NAMEMAX 8
|
|
|
|
char name[SLOT_NAMEMAX]; /* name matching [a-z]+ */
|
|
|
|
unsigned int unit; /* instance of name */
|
|
|
|
unsigned int serial; /* global unique number */
|
2012-09-04 09:54:45 -05:00
|
|
|
unsigned int vol; /* current (midi) volume */
|
2012-09-02 17:13:30 -05:00
|
|
|
unsigned int tstate; /* mmc state */
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* audio device with plenty of slots
|
|
|
|
*/
|
|
|
|
struct dev {
|
|
|
|
struct dev *next;
|
|
|
|
struct slot *slot_list; /* audio streams attached */
|
|
|
|
struct midi *midi;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* audio device (while opened)
|
|
|
|
*/
|
2013-09-14 04:36:38 -05:00
|
|
|
struct dev_sio sio;
|
2012-09-02 17:13:30 -05:00
|
|
|
struct aparams par; /* encoding */
|
|
|
|
int pchan, rchan; /* play & rec channels */
|
|
|
|
adata_t *rbuf; /* rec buffer */
|
|
|
|
adata_t *pbuf; /* array of play buffers */
|
|
|
|
#define DEV_PBUF(d) ((d)->pbuf + (d)->poffs * (d)->pchan)
|
|
|
|
int poffs; /* index of current play buf */
|
|
|
|
struct conv enc; /* native->device format */
|
|
|
|
struct conv dec; /* device->native format */
|
|
|
|
unsigned char *encbuf; /* buffer for encoding */
|
|
|
|
unsigned char *decbuf; /* buffer for decoding */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* preallocated audio sub-devices
|
|
|
|
*/
|
|
|
|
#define DEV_NSLOT 8
|
|
|
|
struct slot slot[DEV_NSLOT];
|
|
|
|
unsigned int serial; /* for slot allocation */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* desired parameters
|
|
|
|
*/
|
|
|
|
unsigned int reqmode; /* mode */
|
|
|
|
struct aparams reqpar; /* parameters */
|
|
|
|
int reqpchan, reqrchan; /* play & rec chans */
|
|
|
|
unsigned int reqbufsz; /* buffer size */
|
|
|
|
unsigned int reqround; /* block size */
|
|
|
|
unsigned int reqrate; /* sample rate */
|
|
|
|
unsigned int hold; /* hold the device open ? */
|
|
|
|
unsigned int autovol; /* auto adjust playvol ? */
|
|
|
|
unsigned int autostart; /* don't wait for MMC start */
|
|
|
|
unsigned int refcnt; /* number of openers */
|
|
|
|
#define DEV_NMAX 16 /* max number of devices */
|
|
|
|
unsigned int num; /* device serial number */
|
|
|
|
#define DEV_CFG 0 /* closed */
|
|
|
|
#define DEV_INIT 1 /* stopped */
|
2012-11-30 14:49:29 -06:00
|
|
|
#define DEV_RUN 2 /* playin & recording */
|
2012-11-02 06:48:10 -05:00
|
|
|
unsigned int pstate; /* one of above */
|
2012-09-02 17:13:30 -05:00
|
|
|
char *path; /* sio path */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* actual parameters and runtime state (i.e. once opened)
|
|
|
|
*/
|
|
|
|
unsigned int mode; /* bitmap of MODE_xxx */
|
|
|
|
unsigned int bufsz, round, rate;
|
|
|
|
unsigned int prime;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MIDI time code (MTC)
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
unsigned int origin; /* MTC start time */
|
|
|
|
unsigned int fps; /* MTC frames per second */
|
|
|
|
#define MTC_FPS_24 0
|
|
|
|
#define MTC_FPS_25 1
|
|
|
|
#define MTC_FPS_30 3
|
|
|
|
unsigned int fps_id; /* one of above */
|
|
|
|
unsigned int hr; /* MTC hours */
|
|
|
|
unsigned int min; /* MTC minutes */
|
|
|
|
unsigned int sec; /* MTC seconds */
|
|
|
|
unsigned int fr; /* MTC frames */
|
|
|
|
unsigned int qfr; /* MTC quarter frames */
|
|
|
|
int delta; /* rel. to the last MTC tick */
|
|
|
|
int refs;
|
|
|
|
} mtc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MIDI machine control (MMC)
|
|
|
|
*/
|
|
|
|
#define MMC_OFF 0 /* ignore MMC messages */
|
|
|
|
#define MMC_STOP 1 /* stopped, can't start */
|
|
|
|
#define MMC_START 2 /* attempting to start */
|
|
|
|
#define MMC_RUN 3 /* started */
|
|
|
|
unsigned int tstate; /* one of above */
|
|
|
|
unsigned int master; /* master volume controller */
|
|
|
|
};
|
|
|
|
|
|
|
|
extern struct dev *dev_list;
|
|
|
|
|
|
|
|
void dev_log(struct dev *);
|
|
|
|
void dev_close(struct dev *);
|
|
|
|
struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
|
|
|
|
unsigned int, unsigned int, unsigned int, unsigned int);
|
|
|
|
struct dev *dev_bynum(int);
|
|
|
|
void dev_del(struct dev *);
|
|
|
|
void dev_adjpar(struct dev *, int, int, int, int, int);
|
|
|
|
int dev_init(struct dev *);
|
|
|
|
void dev_done(struct dev *);
|
|
|
|
int dev_getpos(struct dev *);
|
|
|
|
unsigned int dev_roundof(struct dev *, unsigned int);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* interface to hardware device
|
|
|
|
*/
|
|
|
|
void dev_onmove(struct dev *, int);
|
|
|
|
void dev_cycle(struct dev *);
|
|
|
|
|
|
|
|
/*
|
2012-09-04 09:54:45 -05:00
|
|
|
* midi & midi call-backs
|
2012-09-02 17:13:30 -05:00
|
|
|
*/
|
|
|
|
void dev_mmcstart(struct dev *);
|
|
|
|
void dev_mmcstop(struct dev *);
|
|
|
|
void dev_mmcloc(struct dev *, unsigned int);
|
|
|
|
void dev_master(struct dev *, unsigned int);
|
2012-09-04 09:54:45 -05:00
|
|
|
void dev_midi_vol(struct dev *, struct slot *);
|
2012-09-02 17:13:30 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* sio_open(3) like interface for clients
|
|
|
|
*/
|
|
|
|
void slot_log(struct slot *);
|
|
|
|
struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int);
|
|
|
|
void slot_del(struct slot *);
|
|
|
|
void slot_setvol(struct slot *, unsigned int);
|
|
|
|
void slot_start(struct slot *);
|
|
|
|
void slot_stop(struct slot *);
|
|
|
|
void slot_read(struct slot *);
|
|
|
|
void slot_write(struct slot *);
|
|
|
|
|
|
|
|
#endif /* !defined(DEV_H) */
|