29#ifdef HAVE_KERNEL_OPTION_HEADERS
64#define FEEDER_CHAIN_LEAN 0
65#define FEEDER_CHAIN_16 1
66#define FEEDER_CHAIN_32 2
67#define FEEDER_CHAIN_MULTI 3
68#define FEEDER_CHAIN_FULLMULTI 4
69#define FEEDER_CHAIN_LAST 5
71#if defined(SND_FEEDER_FULL_MULTIFORMAT)
72#define FEEDER_CHAIN_DEFAULT FEEDER_CHAIN_FULLMULTI
73#elif defined(SND_FEEDER_MULTIFORMAT)
74#define FEEDER_CHAIN_DEFAULT FEEDER_CHAIN_MULTI
76#define FEEDER_CHAIN_DEFAULT FEEDER_CHAIN_LEAN
86 AFMT_S16_NE, AFMT_S32_NE,
104 AFMT_S16_LE, AFMT_S16_BE, AFMT_U16_LE, AFMT_U16_BE,
105 AFMT_S24_LE, AFMT_S24_BE, AFMT_U24_LE, AFMT_U24_BE,
106 AFMT_S32_LE, AFMT_S32_BE, AFMT_U32_LE, AFMT_U32_BE,
113 AFMT_S16_LE, AFMT_S16_BE, AFMT_U16_LE, AFMT_U16_BE,
114 AFMT_S24_LE, AFMT_S24_BE, AFMT_U24_LE, AFMT_U24_BE,
115 AFMT_S32_LE, AFMT_S32_BE, AFMT_U32_LE, AFMT_U32_BE,
129#if defined(_KERNEL) && defined(SND_DEBUG) && defined(SND_FEEDER_FULL_MULTIFORMAT)
133 "(0=lean, 1=16bit, 2=32bit, 3=multiformat, 4=fullmultiformat)");
154 device_printf(
c->
dev,
155 "%s(): can't find feeder_format\n", __func__);
164 device_printf(
c->
dev,
165 "%s(): can't add feeder_format\n", __func__);
227 device_printf(
c->
dev,
228 "%s(): can't find feeder_rate\n", __func__);
237 device_printf(
c->
dev,
238 "%s(): can't add feeder_rate\n", __func__);
252 if (cdesc->
dummy != 0) {
255 device_printf(
c->
dev,
256 "%s(): can't set resampling quality\n", __func__);
263 device_printf(
c->
dev,
264 "%s(): can't set source rate\n", __func__);
270 device_printf(
c->
dev,
271 "%s(): can't set destination rate\n", __func__);
305 device_printf(
c->
dev,
306 "%s(): can't find feeder_matrix\n", __func__);
316 device_printf(
c->
dev,
317 "%s(): can't add feeder_matrix\n", __func__);
325 device_printf(
c->
dev,
326 "%s(): feeder_matrix_setup() failed\n", __func__);
362 device_printf(
c->
dev,
363 "%s(): can't find feeder_volume\n", __func__);
372 device_printf(
c->
dev,
373 "%s(): can't add feeder_volume\n", __func__);
384 if (cdesc->
dummy != 0) {
387 device_printf(
c->
dev,
388 "%s(): can't set volume bypass\n", __func__);
395 device_printf(
c->
dev,
396 "%s(): feeder_volume_apply_matrix() failed\n", __func__);
430 device_printf(
c->
dev,
431 "%s(): can't find feeder_eq\n", __func__);
440 device_printf(
c->
dev,
441 "%s(): can't add feeder_eq\n", __func__);
449 device_printf(
c->
dev,
450 "%s(): can't set rate on feeder_eq\n", __func__);
472 device_printf(
c->
dev,
473 "%s(): can't find feeder_root\n", __func__);
479 device_printf(
c->
dev,
480 "%s(): can't add feeder_root\n", __func__);
510 device_printf(
c->
dev,
511 "%s(): can't find feeder_mixer\n", __func__);
520 device_printf(
c->
dev,
521 "%s(): can't add feeder_mixer\n", __func__);
531#define FEEDER_BW(c, t) ((c)->t.matrix->channels * (c)->t.rate)
533#define FEEDRATE_UP(c) ((c)->target.rate > (c)->current.rate)
534#define FEEDRATE_DOWN(c) ((c)->target.rate < (c)->current.rate)
535#define FEEDRATE_REQUIRED(c) (FEEDRATE_UP(c) || FEEDRATE_DOWN(c))
537#define FEEDMATRIX_UP(c) ((c)->target.matrix->channels > \
538 (c)->current.matrix->channels)
539#define FEEDMATRIX_DOWN(c) ((c)->target.matrix->channels < \
540 (c)->current.matrix->channels)
541#define FEEDMATRIX_REQUIRED(c) (FEEDMATRIX_UP(c) || \
542 FEEDMATRIX_DOWN(c) || (c)->use_matrix != 0)
544#define FEEDFORMAT_REQUIRED(c) (AFMT_ENCODING((c)->current.afmt) != \
545 AFMT_ENCODING((c)->target.afmt))
547#define FEEDVOLUME_REQUIRED(c) ((c)->use_volume != 0)
549#define FEEDEQ_VALIDRATE(c, t) (feeder_eq_validrate((c)->t.rate) != 0)
550#define FEEDEQ_ECONOMY(c) (FEEDER_BW(c, current) < FEEDER_BW(c, target))
551#define FEEDEQ_REQUIRED(c) ((c)->use_eq != 0 && \
552 FEEDEQ_VALIDRATE(c, current))
554#define FEEDFORMAT_NE_REQUIRED(c) \
555 ((c)->afmt_ne != AFMT_S32_NE && \
556 (((c)->mode == FEEDER_CHAIN_16 && \
557 AFMT_ENCODING((c)->current.afmt) != AFMT_S16_NE) || \
558 ((c)->mode == FEEDER_CHAIN_32 && \
559 AFMT_ENCODING((c)->current.afmt) != AFMT_S32_NE) || \
560 (c)->mode == FEEDER_CHAIN_FULLMULTI || \
561 ((c)->mode == FEEDER_CHAIN_MULTI && \
562 ((c)->current.afmt & AFMT_8BIT)) || \
563 ((c)->mode == FEEDER_CHAIN_LEAN && \
564 !((c)->current.afmt & (AFMT_S16_NE | AFMT_S32_NE)))))
571 memset(
m, 0,
sizeof(*
m));
587 uint32_t hwfmt, softfmt;
596 KASSERT(
c->
feeder == NULL, (
"feeder chain not empty"));
599 bzero(&cdesc,
sizeof(cdesc));
605#if defined(SND_FEEDER_MULTIFORMAT) || defined(SND_FEEDER_FULL_MULTIFORMAT)
608#if defined(SND_FEEDER_FULL_MULTIFORMAT)
620#define VCHAN_PASSTHROUGH(c) (((c)->flags & (CHN_F_VIRTUAL | \
621 CHN_F_PASSTHROUGH)) == \
622 (CHN_F_VIRTUAL | CHN_F_PASSTHROUGH))
629 if (caps == NULL || caps->
fmtlist == NULL) {
630 device_printf(
c->
dev,
631 "%s(): failed to get channel caps\n", __func__);
641 device_printf(
c->
dev,
642 "%s(): invalid hardware format 0x%08x\n",
646 for (i = 0; caps->
fmtlist[i] != 0; i++)
647 printf(
"0x%08x\n", caps->
fmtlist[i]);
648 printf(
"Req: 0x%08x\n",
c->
format);
659 if (hwmatrix == NULL) {
674 if (softmatrix == NULL) {
686 device_printf(
c->
dev,
687 "%s(): WARNING: %s Soft format 0x%08x -> 0x%08x\n",
739 if (cdesc.
dummy == 0 &&
754 device_printf(
c->
dev,
755 "%s(): snd_fmtbest failed!\n", __func__);
757 (((cdesc.
dummy != 0) ? softfmt :
760 AFMT_S32_NE : AFMT_S16_NE;
771#define FEEDER_BUILD(t) do { \
772 ret = feeder_build_##t(c, &cdesc); \
unsigned int sndbuf_getspd(struct snd_dbuf *b)
void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd)
int sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt)
struct pcmchan_caps * chn_getcaps(struct pcm_channel *c)
int snd_fmtvalid(uint32_t fmt, uint32_t *fmtlist)
void chn_syncstate(struct pcm_channel *c)
#define CHN_BITPERFECT(c)
#define CHN_LOCKASSERT(c)
struct pcmchan_matrix * m
struct feeder_class * feeder_getclass(struct pcm_feederdesc *desc)
u_int32_t snd_fmtbest(u_int32_t fmt, u_int32_t *fmts)
int chn_addfeeder(struct pcm_channel *c, struct feeder_class *fc, struct pcm_feederdesc *desc)
int chn_removefeeder(struct pcm_channel *c)
int feeder_matrix_setup(struct pcm_feeder *, struct pcmchan_matrix *, struct pcmchan_matrix *)
struct pcmchan_matrix * feeder_matrix_format_map(uint32_t)
int feeder_matrix_compare(struct pcmchan_matrix *, struct pcmchan_matrix *)
int feeder_volume_apply_matrix(struct pcm_feeder *, struct pcmchan_matrix *)
#define FEEDMATRIX_REQUIRED(c)
#define FEEDEQ_REQUIRED(c)
#define FEEDFORMAT_REQUIRED(c)
#define VCHAN_PASSTHROUGH(c)
static uint32_t feeder_chain_formats_fullmulti[]
#define FEEDER_CHAIN_LAST
static int feeder_chain_mode
static int feeder_build_volume(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define FEEDMATRIX_DOWN(c)
static uint32_t feeder_chain_formats_16[]
static int feeder_build_format(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define FEEDER_CHAIN_LEAN
SND_DECLARE_FILE("$FreeBSD$")
static uint32_t * feeder_chain_formats[FEEDER_CHAIN_LAST]
static int feeder_build_root(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define FEEDER_CHAIN_DEFAULT
static void feeder_default_matrix(struct pcmchan_matrix *m, uint32_t fmt, int id)
#define FEEDEQ_VALIDRATE(c, t)
#define FEEDER_CHAIN_MULTI
static int feeder_build_matrix(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
static int feeder_build_eq(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define FEEDVOLUME_REQUIRED(c)
static uint32_t feeder_chain_formats_32[]
int feeder_chain(struct pcm_channel *c)
static uint32_t feeder_chain_formats_lean[]
static int feeder_build_rate(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define FEEDFORMAT_NE_REQUIRED(c)
static int feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
static uint32_t feeder_chain_formats_multi[]
#define FEEDER_CHAIN_FULLMULTI
#define FEEDEQ_ECONOMY(c)
#define FEEDRATE_REQUIRED(c)
static int feeder_build_formatne(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
#define SND_CHN_MATRIX_PCMCHANNEL
#define SND_CHN_MATRIX_UNKNOWN
SYSCTL_INT(_hw_midi, OID_AUTO, debug, CTLFLAG_RW, &midi_debug, 0, "")
#define SND_FORMAT(f, c, e)
#define AFMT_EXTCHANNEL(v)
struct feeder_chain_state origin
struct pcm_feederdesc desc
struct feeder_chain_state current
struct feeder_chain_state target
struct pcmchan_matrix * matrix
struct snd_dbuf * bufhard
struct snd_dbuf * bufsoft
struct pcm_channel * parentchannel
struct pcm_feeder * feeder
struct pcmchan_matrix matrix_scratch
struct pcmchan_matrix matrix
struct snddev_info * parentsnddev
struct pcm_feederdesc * desc
int8_t offset[SND_CHN_T_MAX]