summaryrefslogtreecommitdiff
path: root/usr.bin/aucat/abuf.h
blob: 2440393ea4c6ab7b105b0183d7500a4b0a16a30d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*	$OpenBSD: abuf.h,v 1.25 2012/04/11 06:05:43 ratchov Exp $	*/
/*
 * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.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 ABUF_H
#define ABUF_H

#include <sys/queue.h>

struct aproc;
struct aparams;

struct abuf {
	LIST_ENTRY(abuf) ient;	/* reader's list of inputs entry */
	LIST_ENTRY(abuf) oent;	/* writer's list of outputs entry */

	/*
	 * fifo parameters
	 */
	unsigned int bpf;		/* bytes per frame */
	unsigned int cmin, cmax;	/* channel range of this buf */
	unsigned int start;		/* offset where data starts */
	unsigned int used;		/* valid data */
	unsigned int len;		/* size of the ring */
	struct aproc *rproc;		/* reader */
	struct aproc *wproc;		/* writer */
	struct abuf *duplex;		/* link to buffer of the other dir */
	unsigned int inuse;		/* in abuf_{flush,fill,run}() */
	unsigned int tickets;		/* max data to (if throttling) */

	/*
	 * Misc reader aproc-specific per-buffer parameters.
	 */
	union {
		struct {
			int weight;		/* dynamic range */	
			int maxweight;		/* max dynamic range allowed */
			unsigned int vol;	/* volume within the vol */
			unsigned int done;	/* frames ready */
			unsigned int xrun;	/* underrun policy */
			int drop;		/* to drop on next read */
		} mix;
		struct {
			unsigned int st;	/* MIDI running status */
			unsigned int used;	/* bytes used from ``msg'' */
			unsigned int idx;	/* actual MIDI message size */
			unsigned int len;	/* MIDI message length */
#define MIDI_MSGMAX	16			/* max size of MIDI msg */
			unsigned char msg[MIDI_MSGMAX];
		} midi;
	} r;

	/*
	 * Misc reader aproc-specific per-buffer parameters.
	 */
	union {
		struct {
			unsigned int todo;	/* frames to process */
		} mix;
		struct {
			unsigned int done;	/* frames copied */
			unsigned int xrun;	/* one of XRUN_XXX */
			int silence;		/* to add on next write */
		} sub;
		struct {
			struct abuf *owner;	/* current input stream */
		} midi;
	} w;
};

/*
 * the buffer contains at least one frame. This macro should
 * be used to check if the buffer can be flushed
 */
#define ABUF_ROK(b) ((b)->used > 0)

/*
 * there's room for at least one frame
 */
#define ABUF_WOK(b) ((b)->len - (b)->used > 0)

/*
 * the buffer is empty and has no writer anymore
 */
#define ABUF_EOF(b) (!ABUF_ROK(b) && (b)->wproc == NULL)

/*
 * the buffer has no reader anymore, note that it's not
 * enough the buffer to be disconnected, because it can
 * be not yet connected buffer (eg. socket play buffer)
 */
#define ABUF_HUP(b) (!ABUF_WOK(b) && (b)->rproc == NULL)

struct abuf *abuf_new(unsigned int, struct aparams *);
void abuf_del(struct abuf *);
void abuf_dbg(struct abuf *);
void abuf_clear(struct abuf *);
unsigned char *abuf_rgetblk(struct abuf *, unsigned int *, unsigned int);
unsigned char *abuf_wgetblk(struct abuf *, unsigned int *, unsigned int);
void abuf_rdiscard(struct abuf *, unsigned int);
void abuf_wcommit(struct abuf *, unsigned int);
int abuf_fill(struct abuf *);
int abuf_flush(struct abuf *);
void abuf_eof(struct abuf *);
void abuf_hup(struct abuf *);
void abuf_run(struct abuf *);
void abuf_ipos(struct abuf *, int);
void abuf_opos(struct abuf *, int);

#endif /* !defined(ABUF_H) */