58#define PCM_SG_LOCK() mtx_lock(&snd_pcm_syncgroups_mtx)
59#define PCM_SG_TRYLOCK() mtx_trylock(&snd_pcm_syncgroups_mtx)
60#define PCM_SG_UNLOCK() mtx_unlock(&snd_pcm_syncgroups_mtx)
61#define PCM_SG_LOCKASSERT(arg) mtx_assert(&snd_pcm_syncgroups_mtx, arg)
82#define CHN_COMM_UNUSED "<UNUSED>"
83#define CHN_COMM_UNKNOWN "<UNKNOWN>"
141#ifdef OSSV4_EXPERIMENT
175#define CHN_HEAD(x, y) &(x)->y.head
176#define CHN_INIT(x, y) SLIST_INIT(CHN_HEAD(x, y))
177#define CHN_LINK(y) y.link
178#define CHN_EMPTY(x, y) SLIST_EMPTY(CHN_HEAD(x, y))
179#define CHN_FIRST(x, y) SLIST_FIRST(CHN_HEAD(x, y))
181#define CHN_FOREACH(x, y, z) \
182 SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z))
184#define CHN_FOREACH_SAFE(w, x, y, z) \
185 SLIST_FOREACH_SAFE(w, CHN_HEAD(x, z), CHN_LINK(z), y)
187#define CHN_INSERT_HEAD(x, y, z) \
188 SLIST_INSERT_HEAD(CHN_HEAD(x, z), y, CHN_LINK(z))
190#define CHN_INSERT_AFTER(x, y, z) \
191 SLIST_INSERT_AFTER(x, y, CHN_LINK(z))
193#define CHN_REMOVE(x, y, z) \
194 SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z))
196#define CHN_INSERT_HEAD_SAFE(x, y, z) do { \
197 struct pcm_channel *t = NULL; \
198 CHN_FOREACH(t, x, z) { \
203 CHN_INSERT_HEAD(x, y, z); \
206#define CHN_INSERT_AFTER_SAFE(w, x, y, z) do { \
207 struct pcm_channel *t = NULL; \
208 CHN_FOREACH(t, w, z) { \
213 CHN_INSERT_AFTER(x, y, z); \
216#define CHN_REMOVE_SAFE(x, y, z) do { \
217 struct pcm_channel *t = NULL; \
218 CHN_FOREACH(t, x, z) { \
223 CHN_REMOVE(x, y, z); \
226#define CHN_INSERT_SORT(w, x, y, z) do { \
227 struct pcm_channel *t, *a = NULL; \
228 CHN_FOREACH(t, x, z) { \
229 if ((y)->unit w t->unit) \
235 CHN_INSERT_AFTER(a, y, z); \
237 CHN_INSERT_HEAD(x, y, z); \
240#define CHN_INSERT_SORT_ASCEND(x, y, z) CHN_INSERT_SORT(>, x, y, z)
241#define CHN_INSERT_SORT_DESCEND(x, y, z) CHN_INSERT_SORT(<, x, y, z)
243#define CHN_UNIT(x) (snd_unit2u((x)->unit))
244#define CHN_DEV(x) (snd_unit2d((x)->unit))
245#define CHN_CHAN(x) (snd_unit2c((x)->unit))
247#define CHN_BUF_PARENT(x, y) \
248 (((x) != NULL && (x)->parentchannel != NULL && \
249 (x)->parentchannel->bufhard != NULL) ? \
250 (x)->parentchannel->bufhard : (y))
252#define CHN_BROADCAST(x) do { \
253 if ((x)->cv_waiters != 0) \
254 cv_broadcastpri(x, PRIBIO); \
257#include "channel_if.h"
307#define CHN_SETVOLUME(...) chn_setvolume_matrix(__VA_ARGS__)
308#if defined(SND_DIAGNOSTIC) || defined(INVARIANTS)
309#define CHN_GETVOLUME(...) chn_getvolume_matrix(__VA_ARGS__)
311#define CHN_GETVOLUME(x, y, z) ((x)->volume[y][z])
314#define CHN_GETMUTE(x, y, z) ((x)->muted[y][z])
316#ifdef OSSV4_EXPERIMENT
320#define CHN_LOCKOWNED(c) mtx_owned((c)->lock)
321#define CHN_LOCK(c) mtx_lock((c)->lock)
322#define CHN_UNLOCK(c) mtx_unlock((c)->lock)
323#define CHN_TRYLOCK(c) mtx_trylock((c)->lock)
324#define CHN_LOCKASSERT(c) mtx_assert((c)->lock, MA_OWNED)
325#define CHN_UNLOCKASSERT(c) mtx_assert((c)->lock, MA_NOTOWNED)
332#define AFMTSTR_LEN 16
340#define PCMDIR_PLAY_VIRTUAL 2
342#define PCMDIR_REC_VIRTUAL -2
344#define PCMTRIG_START 1
345#define PCMTRIG_EMLDMAWR 2
346#define PCMTRIG_EMLDMARD 3
347#define PCMTRIG_STOP 0
348#define PCMTRIG_ABORT -1
350#define PCMTRIG_COMMON(x) ((x) == PCMTRIG_START || \
351 (x) == PCMTRIG_STOP || \
352 (x) == PCMTRIG_ABORT)
354#define CHN_F_CLOSING 0x00000001
355#define CHN_F_ABORTING 0x00000002
356#define CHN_F_RUNNING 0x00000004
357#define CHN_F_TRIGGERED 0x00000008
358#define CHN_F_NOTRIGGER 0x00000010
359#define CHN_F_SLEEPING 0x00000020
361#define CHN_F_NBIO 0x00000040
362#define CHN_F_MMAP 0x00000080
364#define CHN_F_BUSY 0x00000100
365#define CHN_F_DIRTY 0x00000200
366#define CHN_F_DEAD 0x00000400
367#define CHN_F_SILENCE 0x00000800
369#define CHN_F_HAS_SIZE 0x00001000
370#define CHN_F_HAS_VCHAN 0x00002000
372#define CHN_F_VCHAN_PASSTHROUGH 0x00004000
373#define CHN_F_VCHAN_ADAPTIVE 0x00008000
374#define CHN_F_VCHAN_DYNAMIC (CHN_F_VCHAN_PASSTHROUGH | CHN_F_VCHAN_ADAPTIVE)
376#define CHN_F_VIRTUAL 0x10000000
377#define CHN_F_BITPERFECT 0x20000000
378#define CHN_F_PASSTHROUGH 0x40000000
379#define CHN_F_EXCLUSIVE 0x80000000
381#define CHN_F_BITS "\020" \
396 "\017VCHAN_PASSTHROUGH" \
397 "\020VCHAN_ADAPTIVE" \
403#define CHN_F_RESET (CHN_F_BUSY | CHN_F_DEAD | \
404 CHN_F_VIRTUAL | CHN_F_HAS_VCHAN | \
405 CHN_F_VCHAN_DYNAMIC | \
406 CHN_F_PASSTHROUGH | CHN_F_EXCLUSIVE)
408#define CHN_F_MMAP_INVALID (CHN_F_DEAD | CHN_F_RUNNING)
412#define CHN_N_RATE 0x00000001
413#define CHN_N_FORMAT 0x00000002
414#define CHN_N_VOLUME 0x00000004
415#define CHN_N_BLOCKSIZE 0x00000008
416#define CHN_N_TRIGGER 0x00000010
418#define CHN_LATENCY_MIN 0
419#define CHN_LATENCY_MAX 10
420#define CHN_LATENCY_DEFAULT 2
421#define CHN_POLICY_MIN CHN_LATENCY_MIN
422#define CHN_POLICY_MAX CHN_LATENCY_MAX
423#define CHN_POLICY_DEFAULT CHN_LATENCY_DEFAULT
425#define CHN_LATENCY_PROFILE_MIN 0
426#define CHN_LATENCY_PROFILE_MAX 1
427#define CHN_LATENCY_PROFILE_DEFAULT CHN_LATENCY_PROFILE_MAX
429#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED)
430#define CHN_STOPPED(c) (!CHN_STARTED(c))
431#define CHN_DIRSTR(c) (((c)->direction == PCMDIR_PLAY) ? \
432 "PCMDIR_PLAY" : "PCMDIR_REC")
433#define CHN_BITPERFECT(c) ((c)->flags & CHN_F_BITPERFECT)
434#define CHN_PASSTHROUGH(c) ((c)->flags & CHN_F_PASSTHROUGH)
437#define CHN_TIMEOUT_MIN 1
438#define CHN_TIMEOUT_MAX 10
445#define CHN_2NDBUFBLKSIZE (2 * 1024)
447#define CHN_2NDBUFBLKNUM (32)
449#define CHN_2NDBUFMAXSIZE (131072)
451#define CHANNEL_DECLARE(name) static DEFINE_CLASS(name, name ## _methods, sizeof(struct kobj))
struct pcm_synclist snd_pcm_syncgroups
syncgroups' master list
void chn_vpc_reset(struct pcm_channel *c, int vc, int force)
int chn_setvolume(struct pcm_channel *c, int left, int right)
int chn_syncdestroy(struct pcm_channel *c)
Remove channel from a sync group, if there is one.
int chn_flush(struct pcm_channel *c)
int chn_kill(struct pcm_channel *c)
int chn_trigger(struct pcm_channel *c, int go)
int chn_read(struct pcm_channel *c, struct uio *buf)
int chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute)
int chn_setspeed(struct pcm_channel *c, uint32_t speed)
uint32_t snd_str2afmt(const char *)
int chn_reset(struct pcm_channel *c, u_int32_t fmt, u_int32_t spd)
int chn_setvolume_multi(struct pcm_channel *c, int vc, int left, int right, int center)
int chn_poll(struct pcm_channel *c, int ev, struct thread *td)
int chn_setlatency(struct pcm_channel *c, int latency)
struct pcmchan_caps * chn_getcaps(struct pcm_channel *c)
int chn_notify(struct pcm_channel *c, u_int32_t flags)
int chn_abort(struct pcm_channel *c)
int chn_oss_getorder(struct pcm_channel *, unsigned long long *)
void chn_intr_locked(struct pcm_channel *c)
int chn_setformat(struct pcm_channel *c, uint32_t format)
int chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt)
int chn_oss_getmask(struct pcm_channel *, uint32_t *)
int chn_reinit(struct pcm_channel *c)
int chn_init(struct pcm_channel *c, void *devinfo, int dir, int direction)
int chn_setmatrix(struct pcm_channel *, struct pcmchan_matrix *)
int snd_fmtvalid(uint32_t fmt, uint32_t *fmtlist)
int chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
int chn_getrates(struct pcm_channel *c, int **rates)
Fetch array of supported discrete sample rates.
void chn_resetbuf(struct pcm_channel *c)
int chn_sync(struct pcm_channel *c, int threshold)
SLIST_HEAD(pcm_synclist, pcmchan_syncgroup) snd_pcm_syncgroups
int chn_getmute_matrix(struct pcm_channel *c, int vc, int vt)
struct pcmchan_matrix * chn_getmatrix(struct pcm_channel *)
void chn_intr(struct pcm_channel *c)
int chn_write(struct pcm_channel *c, struct uio *buf)
u_int32_t chn_getformats(struct pcm_channel *c)
int chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed)
int chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val)
void chn_syncstate(struct pcm_channel *c)
u_int32_t chn_start(struct pcm_channel *c, int force)
int chn_getptr(struct pcm_channel *c)
Queries sound driver for sample-aligned hardware buffer pointer index.
uint32_t snd_afmt2str(uint32_t, char *, size_t)
struct mtx snd_pcm_syncgroups_mtx
Channel sync group lock.
int chn_oss_setorder(struct pcm_channel *, unsigned long long *)
int chn_setmute_multi(struct pcm_channel *c, int vc, int mute)
#define SND_CHN_T_VOL_MAX
struct pcmchan_syncmember * sm
struct pcm_channel::@28 channels
struct pcm_channel::@27 children
struct pcm_channel::@27::@29 busy
struct snd_dbuf * bufhard
struct snd_dbuf * bufsoft
struct pcm_channel * parentchannel
struct pcm_feeder * feeder
int8_t muted[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX]
int16_t volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX]
struct pcm_channel::@28::@30::@32 opened
struct pcmchan_matrix matrix_scratch
struct pcm_channel::@28::@30 pcm
struct snddev_info * parentsnddev
struct pcmchan_matrix::@26 map[SND_CHN_T_MAX+1]
int8_t offset[SND_CHN_T_MAX]
Specifies an audio device sync group.
SLIST_HEAD(, pcmchan_syncmember) members
SLIST_ENTRY(pcmchan_syncgroup) link
Specifies a container for members of a sync group.
SLIST_ENTRY(pcmchan_syncmember) link
struct pcmchan_syncgroup * parent