rework feeder sytem to allow feeders in klds
modify driver capability reporting format to list every audio format seperately- required for above and because we could not previously indicate that mono was unsupported. there should be no functional impact.
This commit is contained in:
parent
76bc70f8bc
commit
9aa3234516
@ -85,12 +85,20 @@ static int ad1816chan_trigger(void *data, int go);
|
||||
static int ad1816chan_getptr(void *data);
|
||||
static pcmchan_caps *ad1816chan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps ad1816_caps = {
|
||||
4000, 55200,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t ad1816_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_MU_LAW,
|
||||
AFMT_STEREO | AFMT_MU_LAW,
|
||||
AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_A_LAW,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps ad1816_caps = {4000, 55200, ad1816_fmt, 0};
|
||||
|
||||
static pcm_channel ad1816_chantemplate = {
|
||||
ad1816chan_init,
|
||||
ad1816chan_setdir,
|
||||
|
@ -55,18 +55,34 @@ static int esschan_trigger(void *data, int go);
|
||||
static int esschan_getptr(void *data);
|
||||
static pcmchan_caps *esschan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps ess_playcaps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_U16_LE | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t ess_pfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps ess_reccaps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_U16_LE | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static pcmchan_caps ess_playcaps = {5000, 49000, ess_pfmt, 0};
|
||||
|
||||
static u_int32_t ess_rfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps ess_reccaps = {5000, 49000, ess_rfmt, 0};
|
||||
|
||||
static pcm_channel ess_chantemplate = {
|
||||
esschan_init,
|
||||
esschan_setdir,
|
||||
|
@ -136,23 +136,38 @@ static int msschan_trigger(void *data, int go);
|
||||
static int msschan_getptr(void *data);
|
||||
static pcmchan_caps *msschan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps mss_caps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t mss_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_MU_LAW,
|
||||
AFMT_STEREO | AFMT_MU_LAW,
|
||||
AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_A_LAW,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps mss_caps = {4000, 48000, mss_fmt, 0};
|
||||
|
||||
static pcmchan_caps guspnp_caps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE | AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t guspnp_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_A_LAW,
|
||||
AFMT_STEREO | AFMT_A_LAW,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps guspnp_caps = {4000, 48000, guspnp_fmt, 0};
|
||||
|
||||
static pcmchan_caps opti931_caps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t opti931_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps opti931_caps = {4000, 48000, opti931_fmt, 0};
|
||||
|
||||
static pcm_channel mss_chantemplate = {
|
||||
msschan_init,
|
||||
|
@ -49,47 +49,54 @@ static int sbchan_trigger(void *data, int go);
|
||||
static int sbchan_getptr(void *data);
|
||||
static pcmchan_caps *sbchan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps sb_playcaps = {
|
||||
4000, 22050,
|
||||
static u_int32_t sb_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_playcaps = {4000, 22050, sb_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sb_reccaps = {
|
||||
4000, 13000,
|
||||
static u_int32_t sb_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_reccaps = {4000, 13000, sb_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_playcaps = {
|
||||
4000, 45000,
|
||||
static u_int32_t sbpro_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_playcaps = {4000, 45000, sbpro_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_reccaps = {
|
||||
4000, 15000,
|
||||
static u_int32_t sbpro_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_reccaps = {4000, 15000, sbpro_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_hcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_hfmt[] = {
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_hcaps = {5000, 45000, sb16_hfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_lcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_lfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_lcaps = {5000, 45000, sb16_lfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16x_caps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t sb16x_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16x_caps = {5000, 49000, sb16x_fmt, 0};
|
||||
|
||||
static pcm_channel sb_chantemplate = {
|
||||
sbchan_init,
|
||||
|
@ -49,47 +49,54 @@ static int sbchan_trigger(void *data, int go);
|
||||
static int sbchan_getptr(void *data);
|
||||
static pcmchan_caps *sbchan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps sb_playcaps = {
|
||||
4000, 22050,
|
||||
static u_int32_t sb_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_playcaps = {4000, 22050, sb_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sb_reccaps = {
|
||||
4000, 13000,
|
||||
static u_int32_t sb_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_reccaps = {4000, 13000, sb_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_playcaps = {
|
||||
4000, 45000,
|
||||
static u_int32_t sbpro_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_playcaps = {4000, 45000, sbpro_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_reccaps = {
|
||||
4000, 15000,
|
||||
static u_int32_t sbpro_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_reccaps = {4000, 15000, sbpro_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_hcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_hfmt[] = {
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_hcaps = {5000, 45000, sb16_hfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_lcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_lfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_lcaps = {5000, 45000, sb16_lfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16x_caps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t sb16x_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16x_caps = {5000, 49000, sb16x_fmt, 0};
|
||||
|
||||
static pcm_channel sb_chantemplate = {
|
||||
sbchan_init,
|
||||
|
@ -49,47 +49,54 @@ static int sbchan_trigger(void *data, int go);
|
||||
static int sbchan_getptr(void *data);
|
||||
static pcmchan_caps *sbchan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps sb_playcaps = {
|
||||
4000, 22050,
|
||||
static u_int32_t sb_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_playcaps = {4000, 22050, sb_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sb_reccaps = {
|
||||
4000, 13000,
|
||||
static u_int32_t sb_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb_reccaps = {4000, 13000, sb_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_playcaps = {
|
||||
4000, 45000,
|
||||
static u_int32_t sbpro_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_playcaps = {4000, 45000, sbpro_playfmt, 0};
|
||||
|
||||
static pcmchan_caps sbpro_reccaps = {
|
||||
4000, 15000,
|
||||
static u_int32_t sbpro_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sbpro_reccaps = {4000, 15000, sbpro_recfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_hcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_hfmt[] = {
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_hcaps = {5000, 45000, sb16_hfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16_lcaps = {
|
||||
5000, 45000,
|
||||
static u_int32_t sb16_lfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16_lcaps = {5000, 45000, sb16_lfmt, 0};
|
||||
|
||||
static pcmchan_caps sb16x_caps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t sb16x_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps sb16x_caps = {5000, 49000, sb16x_fmt, 0};
|
||||
|
||||
static pcm_channel sb_chantemplate = {
|
||||
sbchan_init,
|
||||
|
@ -46,17 +46,23 @@ static int auchan_trigger(void *data, int go);
|
||||
static int auchan_getptr(void *data);
|
||||
static pcmchan_caps *auchan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps au_playcaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t au_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0};
|
||||
|
||||
static pcmchan_caps au_reccaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t au_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0};
|
||||
|
||||
static pcm_channel au_chantemplate = {
|
||||
auchan_init,
|
||||
|
@ -96,17 +96,25 @@ static int csachan_trigger(void *data, int go);
|
||||
static int csachan_getptr(void *data);
|
||||
static pcmchan_caps *csachan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps csa_playcaps = {
|
||||
8000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
};
|
||||
|
||||
static pcmchan_caps csa_reccaps = {
|
||||
11025, 48000,
|
||||
static u_int32_t csa_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
AFMT_S16_BE,
|
||||
AFMT_STEREO | AFMT_S16_BE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0};
|
||||
|
||||
static u_int32_t csa_recfmt[] = {
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
|
||||
|
||||
static pcm_channel csa_chantemplate = {
|
||||
csachan_init,
|
||||
|
@ -184,17 +184,27 @@ static void ds_wr(struct sc_info *, int, u_int32_t, int);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static pcmchan_caps ds_reccaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t ds_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0};
|
||||
|
||||
static pcmchan_caps ds_playcaps = {
|
||||
4000, 96000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t ds_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
|
||||
|
||||
static pcm_channel ds_pchantemplate = {
|
||||
ds1pchan_init,
|
||||
|
@ -154,18 +154,38 @@ static void emu_wr(struct sc_info *, int, u_int32_t, int);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static pcmchan_caps emu_reccaps[3] = {
|
||||
{8000, 48000, AFMT_STEREO | AFMT_S16_LE, AFMT_STEREO | AFMT_S16_LE},
|
||||
{8000, 8000, AFMT_U8, AFMT_U8},
|
||||
{48000, 48000, AFMT_STEREO | AFMT_S16_LE, AFMT_STEREO | AFMT_S16_LE},
|
||||
static u_int32_t emu_rfmt_ac97[] = {
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps emu_playcaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t emu_rfmt_mic[] = {
|
||||
AFMT_U8,
|
||||
0
|
||||
};
|
||||
|
||||
static u_int32_t emu_rfmt_efx[] = {
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps emu_reccaps[3] = {
|
||||
{8000, 48000, emu_rfmt_ac97, 0},
|
||||
{8000, 8000, emu_rfmt_mic, 0},
|
||||
{48000, 48000, emu_rfmt_efx, 0},
|
||||
};
|
||||
|
||||
static u_int32_t emu_pfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
|
||||
static pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
|
||||
|
||||
static pcm_channel emu_chantemplate = {
|
||||
emupchan_init,
|
||||
emupchan_setdir,
|
||||
|
@ -122,17 +122,23 @@ static int eschan_trigger(void *data, int go);
|
||||
static int eschan_getptr(void *data);
|
||||
static pcmchan_caps *eschan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps es_playcaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t es_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps es_playcaps = {4000, 48000, es_playfmt, 0};
|
||||
|
||||
static pcmchan_caps es_reccaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t es_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps es_reccaps = {4000, 48000, es_recfmt, 0};
|
||||
|
||||
static pcm_channel es1370_chantemplate = {
|
||||
eschan_init,
|
||||
|
@ -125,11 +125,14 @@ static int samplerates[9] = {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static pcmchan_caps nm_caps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t nm_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0};
|
||||
|
||||
static pcm_channel nm_chantemplate = {
|
||||
nmchan_init,
|
||||
|
@ -52,20 +52,34 @@ static int esschan_trigger(void *data, int go);
|
||||
static int esschan_getptr(void *data);
|
||||
static pcmchan_caps *esschan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps ess_playcaps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_U16_LE | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t ess_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0};
|
||||
|
||||
/*
|
||||
* Recording output is byte-swapped
|
||||
*/
|
||||
static pcmchan_caps ess_reccaps = {
|
||||
5000, 49000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_U16_BE | AFMT_S16_BE,
|
||||
AFMT_STEREO | AFMT_S16_BE
|
||||
static u_int32_t ess_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_BE,
|
||||
AFMT_STEREO | AFMT_S16_BE,
|
||||
AFMT_U16_BE,
|
||||
AFMT_STEREO | AFMT_U16_BE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0};
|
||||
|
||||
static pcm_channel ess_chantemplate = {
|
||||
esschan_init,
|
||||
|
@ -115,17 +115,31 @@ static void tr_stopch(struct tr_info *, char);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
static pcmchan_caps tr_reccaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t tr_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0};
|
||||
|
||||
static pcmchan_caps tr_playcaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t tr_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0};
|
||||
|
||||
static pcm_channel tr_chantemplate = {
|
||||
trchan_init,
|
||||
|
@ -85,17 +85,23 @@ static int viachan_trigger(void *data, int go);
|
||||
static int viachan_getptr(void *data);
|
||||
static pcmchan_caps *viachan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps via_playcaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t via_playfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0};
|
||||
|
||||
static pcmchan_caps via_reccaps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE
|
||||
static u_int32_t via_recfmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0};
|
||||
|
||||
static pcm_channel via_chantemplate = {
|
||||
viachan_init,
|
||||
|
@ -1127,8 +1127,18 @@ chn_init(pcm_channel *c, void *devinfo, int dir)
|
||||
snd_dbuf *bs = &c->buffer2nd;
|
||||
|
||||
/* Initialize the hardware and DMA buffer first. */
|
||||
c->feeder = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
|
||||
*(c->feeder) = *feeder_getroot();
|
||||
c->feederdesc = malloc(sizeof(*(c->feeder)), M_DEVBUF, M_NOWAIT);
|
||||
c->feederdesc->type = FEEDER_ROOT;
|
||||
c->feederdesc->in = 0;
|
||||
c->feederdesc->out = 0;
|
||||
c->feederdesc->flags = 0;
|
||||
c->feederdesc->idx = 0;
|
||||
c->feeder->desc = c->feederdesc;
|
||||
c->feeder->source = NULL;
|
||||
|
||||
c->flags = 0;
|
||||
c->feeder = &feeder_root;
|
||||
c->buffer.chan = -1;
|
||||
c->devinfo = c->init(devinfo, &c->buffer, c, dir);
|
||||
if (c->devinfo == NULL || c->buffer.bufsize == 0)
|
||||
@ -1181,6 +1191,18 @@ chn_setspeed(pcm_channel *c, int speed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; fmtlist[i]; i++)
|
||||
if (fmt == fmtlist[i])
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
chn_setformat(pcm_channel *c, u_int32_t fmt)
|
||||
{
|
||||
@ -1189,10 +1211,17 @@ chn_setformat(pcm_channel *c, u_int32_t fmt)
|
||||
|
||||
u_int32_t hwfmt;
|
||||
if (CANCHANGE(c)) {
|
||||
while (chn_removefeeder(c) == 0);
|
||||
c->format = fmt;
|
||||
hwfmt = chn_feedchain(c);
|
||||
if ((c->flags & CHN_F_MAPPED) && c->format != hwfmt)
|
||||
return EINVAL;
|
||||
c->feederdesc->out = c->format;
|
||||
hwfmt = c->format;
|
||||
if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist)) {
|
||||
if (c->flags & CHN_F_MAPPED)
|
||||
return EINVAL;
|
||||
hwfmt = chn_feedchain(c, chn_getcaps(c)->fmtlist);
|
||||
if (hwfmt == 0)
|
||||
return EINVAL;
|
||||
}
|
||||
b->fmt = hwfmt;
|
||||
bs->fmt = hwfmt;
|
||||
chn_resetbuf(c);
|
||||
@ -1287,3 +1316,19 @@ chn_getcaps(pcm_channel *c)
|
||||
{
|
||||
return c->getcaps(c->devinfo);
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
chn_getformats(pcm_channel *c)
|
||||
{
|
||||
u_int32_t *fmtlist, fmts;
|
||||
int i;
|
||||
|
||||
fmtlist = chn_getcaps(c)->fmtlist;
|
||||
fmts = 0;
|
||||
for (i = 0; fmtlist[i]; i++)
|
||||
fmts |= fmtlist[i];
|
||||
|
||||
return fmts;
|
||||
}
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ int chn_setblocksize(pcm_channel *c, int blkcnt, int blksz);
|
||||
int chn_trigger(pcm_channel *c, int go);
|
||||
int chn_getptr(pcm_channel *c);
|
||||
pcmchan_caps *chn_getcaps(pcm_channel *c);
|
||||
u_int32_t chn_getformats(pcm_channel *c);
|
||||
|
||||
int chn_allocbuf(snd_dbuf *b, bus_dma_tag_t parent_dmat);
|
||||
void chn_resetbuf(pcm_channel *c);
|
||||
@ -52,11 +53,10 @@ int chn_wrfeed(pcm_channel *c);
|
||||
int chn_rdfeed(pcm_channel *c);
|
||||
int chn_abort(pcm_channel *c);
|
||||
|
||||
int fmtvalid(u_int32_t fmt, u_int32_t *fmtlist);
|
||||
|
||||
void buf_isadma(snd_dbuf *b, int go);
|
||||
int buf_isadmaptr(snd_dbuf *b);
|
||||
int chn_feedchain(pcm_channel *c);
|
||||
|
||||
extern pcm_feeder feeder_root;
|
||||
|
||||
#define PCMDIR_PLAY 1
|
||||
#define PCMDIR_REC -1
|
||||
|
@ -78,9 +78,24 @@ typedef int (pcmfeed_free_t)(pcm_feeder *feeder);
|
||||
typedef int (pcmfeed_feed_t)(pcm_feeder *feeder, pcm_channel *c, u_int8_t *buffer,
|
||||
u_int32_t count, struct uio *stream);
|
||||
|
||||
#define FEEDER_ROOT 1
|
||||
#define FEEDER_FMT 2
|
||||
#define FEEDER_RATE 3
|
||||
#define FEEDER_FILTER 4
|
||||
|
||||
struct pcm_feederdesc {
|
||||
u_int32_t type;
|
||||
u_int32_t in, out;
|
||||
u_int32_t flags;
|
||||
int idx;
|
||||
};
|
||||
|
||||
#define MAXFEEDERS 256
|
||||
|
||||
struct _pcm_feeder {
|
||||
char name[16];
|
||||
int align;
|
||||
struct pcm_feederdesc *desc;
|
||||
pcmfeed_init_t *init;
|
||||
pcmfeed_free_t *free;
|
||||
pcmfeed_feed_t *feed;
|
||||
@ -90,7 +105,8 @@ struct _pcm_feeder {
|
||||
|
||||
struct _pcmchan_caps {
|
||||
u_int32_t minspeed, maxspeed;
|
||||
u_int32_t formats, bestfmt;
|
||||
u_int32_t *fmtlist;
|
||||
u_int32_t caps;
|
||||
};
|
||||
|
||||
typedef void *(pcmchan_init_t)(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir);
|
||||
@ -112,6 +128,7 @@ struct _pcm_channel {
|
||||
pcmchan_getptr_t *getptr;
|
||||
pcmchan_getcaps_t *getcaps;
|
||||
pcm_feeder *feeder;
|
||||
struct pcm_feederdesc *feederdesc;
|
||||
u_int32_t align;
|
||||
|
||||
int volume;
|
||||
|
@ -283,8 +283,8 @@ dsp_ioctl(snddev_info *d, int chan, u_long cmd, caddr_t arg)
|
||||
p->bufsize = min(rdch? rdch->buffer2nd.bufsize : 1000000,
|
||||
wrch? wrch->buffer2nd.bufsize : 1000000);
|
||||
/* XXX bad on sb16 */
|
||||
p->formats = (rcaps? rcaps->formats : 0xffffffff) &
|
||||
(pcaps? pcaps->formats : 0xffffffff);
|
||||
p->formats = (rdch? chn_getformats(rdch) : 0xffffffff) &
|
||||
(wrch? chn_getformats(wrch) : 0xffffffff);
|
||||
if (rdch && wrch)
|
||||
p->formats |= (d->flags & SD_F_SIMPLEX)? 0 : AFMT_FULLDUPLEX;
|
||||
p->mixers = 1; /* default: one mixer */
|
||||
@ -406,7 +406,7 @@ dsp_ioctl(snddev_info *d, int chan, u_long cmd, caddr_t arg)
|
||||
break;
|
||||
|
||||
case SNDCTL_DSP_GETFMTS: /* returns a mask of supported fmts */
|
||||
*arg_i = wrch? chn_getcaps(wrch)->formats : chn_getcaps(rdch)->formats;
|
||||
*arg_i = wrch? chn_getformats(wrch) : chn_getformats(rdch);
|
||||
break ;
|
||||
|
||||
case SNDCTL_DSP_SETFMT: /* sets _one_ format */
|
||||
|
@ -38,10 +38,22 @@ static int fkchan_trigger(void *data, int go);
|
||||
static int fkchan_getptr(void *data);
|
||||
static pcmchan_caps *fkchan_getcaps(void *data);
|
||||
|
||||
static pcmchan_caps fk_caps = {
|
||||
4000, 48000,
|
||||
AFMT_STEREO | AFMT_U8 | AFMT_S8 | AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE
|
||||
static u_int32_t fk_fmt[] = {
|
||||
AFMT_U8,
|
||||
AFMT_STEREO | AFMT_U8,
|
||||
AFMT_S8,
|
||||
AFMT_STEREO | AFMT_S8,
|
||||
AFMT_S16_LE,
|
||||
AFMT_STEREO | AFMT_S16_LE,
|
||||
AFMT_U16_LE,
|
||||
AFMT_STEREO | AFMT_U16_LE,
|
||||
AFMT_S16_BE,
|
||||
AFMT_STEREO | AFMT_S16_BE,
|
||||
AFMT_U16_BE,
|
||||
AFMT_STEREO | AFMT_U16_BE,
|
||||
0
|
||||
};
|
||||
static pcmchan_caps fk_caps = {4000, 48000, fk_fmt, 0};
|
||||
|
||||
static pcm_channel fk_chantemplate = {
|
||||
fkchan_init,
|
||||
|
@ -28,9 +28,6 @@
|
||||
|
||||
#include <dev/sound/pcm/sound.h>
|
||||
|
||||
static int chn_addfeeder(pcm_channel *c, pcm_feeder *f);
|
||||
static int chn_removefeeder(pcm_channel *c);
|
||||
|
||||
#define FEEDBUFSZ 8192
|
||||
|
||||
static unsigned char ulaw_to_u8[] = {
|
||||
@ -103,15 +100,65 @@ static unsigned char u8_to_ulaw[] = {
|
||||
129, 129, 129, 129, 128, 128, 128, 128,
|
||||
};
|
||||
|
||||
struct feedertab_entry {
|
||||
SLIST_ENTRY(feedertab_entry) link;
|
||||
pcm_feeder *feeder;
|
||||
struct pcm_feederdesc *desc;
|
||||
|
||||
int idx;
|
||||
};
|
||||
static SLIST_HEAD(, feedertab_entry) feedertab;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
feeder_register(void *p)
|
||||
{
|
||||
pcm_feeder *f = p;
|
||||
struct feedertab_entry *fte;
|
||||
static int feedercnt = 0;
|
||||
int i;
|
||||
|
||||
if (feedercnt == 0) {
|
||||
if (f->desc)
|
||||
panic("FIRST FEEDER NOT ROOT: %s\n", f->name);
|
||||
SLIST_INIT(&feedertab);
|
||||
fte = malloc(sizeof(*fte), M_DEVBUF, M_NOWAIT);
|
||||
fte->feeder = f;
|
||||
fte->desc = NULL;
|
||||
fte->idx = feedercnt;
|
||||
SLIST_INSERT_HEAD(&feedertab, fte, link);
|
||||
feedercnt++;
|
||||
return;
|
||||
}
|
||||
/* printf("installing feeder: %s\n", f->name); */
|
||||
|
||||
i = 0;
|
||||
while ((feedercnt < MAXFEEDERS) && (f->desc[i].type > 0)) {
|
||||
fte = malloc(sizeof(*fte), M_DEVBUF, M_NOWAIT);
|
||||
fte->feeder = f;
|
||||
fte->desc = &f->desc[i];
|
||||
fte->idx = feedercnt;
|
||||
fte->desc->idx = feedercnt;
|
||||
SLIST_INSERT_HEAD(&feedertab, fte, link);
|
||||
i++;
|
||||
}
|
||||
feedercnt++;
|
||||
if (feedercnt >= MAXFEEDERS)
|
||||
printf("MAXFEEDERS exceeded\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
feed_root(pcm_feeder *feeder, pcm_channel *ch, u_int8_t *buffer, u_int32_t count, struct uio *stream)
|
||||
{
|
||||
int ret, c = 0, s;
|
||||
int ret, s;
|
||||
|
||||
KASSERT(count, ("feed_root: count == 0"));
|
||||
count &= ~((1 << ch->align) - 1);
|
||||
KASSERT(count, ("feed_root: aligned count == 0"));
|
||||
|
||||
s = spltty();
|
||||
count = min(count, stream->uio_resid);
|
||||
if (count) {
|
||||
@ -119,16 +166,19 @@ feed_root(pcm_feeder *feeder, pcm_channel *ch, u_int8_t *buffer, u_int32_t count
|
||||
KASSERT(ret == 0, ("feed_root: uiomove failed"));
|
||||
}
|
||||
splx(s);
|
||||
return c + count;
|
||||
|
||||
return count;
|
||||
}
|
||||
pcm_feeder feeder_root = { "root", 0, NULL, NULL, feed_root };
|
||||
static pcm_feeder feeder_root = { "root", 0, NULL, NULL, NULL, feed_root };
|
||||
SYSINIT(feeder_root, SI_SUB_DRIVERS, SI_ORDER_FIRST, feeder_register, &feeder_root);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
feed_8to16(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
feed_8to16le(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
k = f->source->feed(f->source, c, b, count / 2, stream);
|
||||
j = k - 1;
|
||||
i = j * 2 + 1;
|
||||
@ -138,7 +188,17 @@ feed_8to16(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct u
|
||||
}
|
||||
return k * 2;
|
||||
}
|
||||
static pcm_feeder feeder_8to16 = { "8to16", 0, NULL, NULL, feed_8to16 };
|
||||
|
||||
static struct pcm_feederdesc desc_8to16le[] = {
|
||||
{FEEDER_FMT, AFMT_U8, AFMT_U16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S8, AFMT_S16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_8to16le =
|
||||
{ "8to16le", 0, desc_8to16le, NULL, NULL, feed_8to16le };
|
||||
SYSINIT(feeder_8to16le, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_8to16le);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -158,10 +218,11 @@ feed_16to8_free(pcm_feeder *f)
|
||||
}
|
||||
|
||||
static int
|
||||
feed_16to8le(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
feed_16leto8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
{
|
||||
u_int32_t i = 0, toget = count * 2;
|
||||
int j = 1, k;
|
||||
|
||||
k = f->source->feed(f->source, c, f->data, min(toget, FEEDBUFSZ), stream);
|
||||
while (j < k) {
|
||||
b[i++] = ((u_int8_t *)f->data)[j];
|
||||
@ -169,8 +230,17 @@ feed_16to8le(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static pcm_feeder feeder_16to8le =
|
||||
{ "16to8le", 1, feed_16to8_init, feed_16to8_free, feed_16to8le };
|
||||
|
||||
static struct pcm_feederdesc desc_16leto8[] = {
|
||||
{FEEDER_FMT, AFMT_U16_LE, AFMT_U8, 0},
|
||||
{FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE, AFMT_S8, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_16leto8 =
|
||||
{ "16leto8", 1, desc_16leto8, feed_16to8_init, feed_16to8_free, feed_16leto8 };
|
||||
SYSINIT(feeder_16leto8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_16leto8);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -178,6 +248,7 @@ static int
|
||||
feed_monotostereo8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
{
|
||||
int i, j, k = f->source->feed(f->source, c, b, count / 2, stream);
|
||||
|
||||
j = k - 1;
|
||||
i = j * 2 + 1;
|
||||
while (i > 0 && j >= 0) {
|
||||
@ -187,8 +258,15 @@ feed_monotostereo8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count,
|
||||
}
|
||||
return k * 2;
|
||||
}
|
||||
|
||||
static struct pcm_feederdesc desc_monotostereo8[] = {
|
||||
{FEEDER_FMT, AFMT_U8, AFMT_U8 | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S8, AFMT_S8 | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_monotostereo8 =
|
||||
{ "monotostereo8", 0, NULL, NULL, feed_monotostereo8 };
|
||||
{ "monotostereo8", 0, desc_monotostereo8, NULL, NULL, feed_monotostereo8 };
|
||||
SYSINIT(feeder_monotostereo8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_monotostereo8);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -212,6 +290,7 @@ feed_stereotomono8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count,
|
||||
{
|
||||
u_int32_t i = 0, toget = count * 2;
|
||||
int j = 0, k;
|
||||
|
||||
k = f->source->feed(f->source, c, f->data, min(toget, FEEDBUFSZ), stream);
|
||||
while (j < k) {
|
||||
b[i++] = ((u_int8_t *)f->data)[j];
|
||||
@ -219,9 +298,15 @@ feed_stereotomono8(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count,
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct pcm_feederdesc desc_stereotomono8[] = {
|
||||
{FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_U8, 0},
|
||||
{FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_S8, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_stereotomono8 =
|
||||
{ "stereotomono8", 1, feed_stereotomono8_init, feed_stereotomono8_free,
|
||||
feed_stereotomono8 };
|
||||
{ "stereotomono8", 1, desc_stereotomono8, feed_stereotomono8_init, feed_stereotomono8_free, feed_stereotomono8 };
|
||||
SYSINIT(feeder_stereotomono8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_stereotomono8);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -230,6 +315,7 @@ feed_endian(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct
|
||||
{
|
||||
u_int8_t t;
|
||||
int i = 0, j = f->source->feed(f->source, c, b, count, stream);
|
||||
|
||||
while (i < j) {
|
||||
t = b[i];
|
||||
b[i] = b[i + 1];
|
||||
@ -238,7 +324,20 @@ feed_endian(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static pcm_feeder feeder_endian = { "endian", -1, NULL, NULL, feed_endian };
|
||||
|
||||
static struct pcm_feederdesc desc_endian[] = {
|
||||
{FEEDER_FMT, AFMT_U16_LE, AFMT_U16_BE, 0},
|
||||
{FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_U16_BE | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE, AFMT_S16_BE, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_S16_BE | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_U16_BE, AFMT_U16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_U16_BE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S16_BE, AFMT_S16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_S16_BE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_endian = { "endian", -1, desc_endian, NULL, NULL, feed_endian };
|
||||
SYSINIT(feeder_endian, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_endian);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -247,16 +346,35 @@ feed_sign(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct ui
|
||||
{
|
||||
int i = 0, j = f->source->feed(f->source, c, b, count, stream);
|
||||
int ssz = (int)f->data, ofs = ssz - 1;
|
||||
|
||||
while (i < j) {
|
||||
b[i + ofs] ^= 0x80;
|
||||
i += ssz;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct pcm_feederdesc desc_sign8[] = {
|
||||
{FEEDER_FMT, AFMT_U8, AFMT_S8, 0},
|
||||
{FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_S8 | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S8, AFMT_U8, 0},
|
||||
{FEEDER_FMT, AFMT_S8 | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_sign8 =
|
||||
{ "sign8", 0, NULL, NULL, feed_sign, (void *)1 };
|
||||
static pcm_feeder feeder_sign16 =
|
||||
{ "sign16", -1, NULL, NULL, feed_sign, (void *)2 };
|
||||
{ "sign8", 0, desc_sign8, NULL, NULL, feed_sign, (void *)1 };
|
||||
SYSINIT(feeder_sign8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_sign8);
|
||||
|
||||
static struct pcm_feederdesc desc_sign16le[] = {
|
||||
{FEEDER_FMT, AFMT_U16_LE, AFMT_S16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_U16_LE | AFMT_STEREO, AFMT_S16_LE | AFMT_STEREO, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE, AFMT_U16_LE, 0},
|
||||
{FEEDER_FMT, AFMT_S16_LE | AFMT_STEREO, AFMT_U16_LE | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_sign16le =
|
||||
{ "sign16le", -1, desc_sign16le, NULL, NULL, feed_sign, (void *)2 };
|
||||
SYSINIT(feeder_sign16le, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_sign16le);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -264,147 +382,172 @@ static int
|
||||
feed_table(pcm_feeder *f, pcm_channel *c, u_int8_t *b, u_int32_t count, struct uio *stream)
|
||||
{
|
||||
int i = 0, j = f->source->feed(f->source, c, b, count, stream);
|
||||
|
||||
while (i < j) {
|
||||
b[i] = ((u_int8_t *)f->data)[b[i]];
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static struct pcm_feederdesc desc_ulawtou8[] = {
|
||||
{FEEDER_FMT, AFMT_MU_LAW, AFMT_U8, 0},
|
||||
{FEEDER_FMT, AFMT_MU_LAW | AFMT_STEREO, AFMT_U8 | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_ulawtou8 =
|
||||
{ "ulawtou8", 0, NULL, NULL, feed_table, ulaw_to_u8 };
|
||||
{ "ulawtou8", 0, desc_ulawtou8, NULL, NULL, feed_table, ulaw_to_u8 };
|
||||
SYSINIT(feeder_ulawtou8, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_ulawtou8);
|
||||
|
||||
static struct pcm_feederdesc desc_u8toulaw[] = {
|
||||
{FEEDER_FMT, AFMT_U8, AFMT_MU_LAW, 0},
|
||||
{FEEDER_FMT, AFMT_U8 | AFMT_STEREO, AFMT_MU_LAW | AFMT_STEREO, 0},
|
||||
{0},
|
||||
};
|
||||
static pcm_feeder feeder_u8toulaw =
|
||||
{ "u8toulaw", 0, NULL, NULL, feed_table, u8_to_ulaw };
|
||||
{ "u8toulaw", 0, desc_u8toulaw, NULL, NULL, feed_table, u8_to_ulaw };
|
||||
SYSINIT(feeder_u8toulaw, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, feeder_register, &feeder_u8toulaw);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct fmtspec {
|
||||
int stereo;
|
||||
int sign;
|
||||
int bit16;
|
||||
int bigendian;
|
||||
int ulaw;
|
||||
int bad;
|
||||
};
|
||||
|
||||
struct fmtcvt {
|
||||
pcm_feeder *f;
|
||||
struct fmtspec ispec, ospec;
|
||||
};
|
||||
|
||||
struct fmtcvt cvttab[] = {
|
||||
{&feeder_ulawtou8, {-1, 0, 0, 0, 1}, {-1, 0, 0, 0, 0}},
|
||||
{&feeder_u8toulaw, {-1, 0, 0, 0, 0}, {-1, 0, 0, 0, 1}},
|
||||
{&feeder_sign8, {-1, 0, 0, 0, 0}, {-1, 1, 0, 0, 0}},
|
||||
{&feeder_sign8, {-1, 1, 0, 0, 0}, {-1, 0, 0, 0, 0}},
|
||||
{&feeder_monotostereo8, { 0, -1, 0, 0, -1}, { 1, -1, 0, 0, -1}},
|
||||
{&feeder_stereotomono8, { 1, -1, 0, 0, -1}, { 0, -1, 0, 0, -1}},
|
||||
{&feeder_sign16, {-1, 0, 1, 0, 0}, {-1, 1, 1, 0, 0}},
|
||||
{&feeder_sign16, {-1, 1, 1, 0, 0}, {-1, 0, 1, 0, 0}},
|
||||
{&feeder_8to16, {-1, -1, 0, 0, 0}, {-1, -1, 1, 0, 0}},
|
||||
{&feeder_16to8le, {-1, -1, 1, 0, 0}, {-1, -1, 0, 0, 0}},
|
||||
{&feeder_endian, {-1, -1, 1, 0, 0}, {-1, -1, 1, 1, 0}},
|
||||
{&feeder_endian, {-1, -1, 1, 1, 0}, {-1, -1, 1, 0, 0}},
|
||||
};
|
||||
#define FEEDERTABSZ (sizeof(cvttab) / sizeof(struct fmtcvt))
|
||||
|
||||
static int
|
||||
getspec(u_int32_t fmt, struct fmtspec *spec)
|
||||
cmpdesc(struct pcm_feederdesc *n, struct pcm_feederdesc *m)
|
||||
{
|
||||
spec->stereo = (fmt & AFMT_STEREO)? 1 : 0;
|
||||
spec->sign = (fmt & AFMT_SIGNED)? 1 : 0;
|
||||
spec->bit16 = (fmt & AFMT_16BIT)? 1 : 0;
|
||||
spec->bigendian = (fmt & AFMT_BIGENDIAN)? 1 : 0;
|
||||
spec->ulaw = (fmt & AFMT_MU_LAW)? 1 : 0;
|
||||
spec->bad = (fmt & (AFMT_A_LAW | AFMT_MPEG))? 1 : 0;
|
||||
return 0;
|
||||
return ((n->type == m->type) && (n->in == m->in) && (n->out == m->out) && (n->flags == m->flags));
|
||||
}
|
||||
|
||||
static int
|
||||
cmp(int x, int y)
|
||||
pcm_feeder *
|
||||
feeder_get(struct pcm_feederdesc *desc)
|
||||
{
|
||||
return (x == -1 || x == y || y == -1)? 1 : 0;
|
||||
struct feedertab_entry *fte;
|
||||
|
||||
SLIST_FOREACH(fte, &feedertab, link) {
|
||||
if ((fte->desc != NULL) && cmpdesc(desc, fte->desc))
|
||||
return fte->feeder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
cmpspec(struct fmtspec *x, struct fmtspec *y)
|
||||
pcm_feeder *
|
||||
feeder_getroot()
|
||||
{
|
||||
int i = 0;
|
||||
if (cmp(x->stereo, y->stereo)) i |= 0x01;
|
||||
if (cmp(x->sign, y->sign)) i |= 0x02;
|
||||
if (cmp(x->bit16, y->bit16)) i |= 0x04;
|
||||
if (cmp(x->bigendian, y->bigendian)) i |= 0x08;
|
||||
if (cmp(x->ulaw, y->ulaw)) i |= 0x10;
|
||||
return i;
|
||||
}
|
||||
struct feedertab_entry *fte;
|
||||
|
||||
static int
|
||||
cvtapply(pcm_channel *c, struct fmtcvt *cvt, struct fmtspec *s)
|
||||
{
|
||||
int i = cmpspec(s, &cvt->ospec);
|
||||
chn_addfeeder(c, cvt->f);
|
||||
if (cvt->ospec.stereo != -1) s->stereo = cvt->ospec.stereo;
|
||||
if (cvt->ospec.sign != -1) s->sign = cvt->ospec.sign;
|
||||
if (cvt->ospec.bit16 != -1) s->bit16 = cvt->ospec.bit16;
|
||||
if (cvt->ospec.bigendian != -1) s->bigendian = cvt->ospec.bigendian;
|
||||
if (cvt->ospec.ulaw != -1) s->ulaw = cvt->ospec.ulaw;
|
||||
return i;
|
||||
SLIST_FOREACH(fte, &feedertab, link) {
|
||||
if (fte->desc == NULL)
|
||||
return fte->feeder;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
chn_feedchain(pcm_channel *c)
|
||||
{
|
||||
int i, chosen, iter;
|
||||
u_int32_t mask;
|
||||
struct fmtspec s, t;
|
||||
struct fmtcvt *e;
|
||||
|
||||
while (chn_removefeeder(c) != -1);
|
||||
c->align = 0;
|
||||
if ((c->format & chn_getcaps(c)->formats) == c->format)
|
||||
return c->format;
|
||||
getspec(c->format, &s);
|
||||
if (s.bad) return -1;
|
||||
getspec(chn_getcaps(c)->bestfmt, &t);
|
||||
mask = (~cmpspec(&s, &t)) & 0x1f;
|
||||
iter = 0;
|
||||
do {
|
||||
if (mask == 0 || iter >= 8) break;
|
||||
chosen = -1;
|
||||
for (i = 0; i < FEEDERTABSZ && chosen == -1; i++) {
|
||||
e = &cvttab[i];
|
||||
if ((cmpspec(&s, &e->ispec) == 0x1f) &&
|
||||
((~cmpspec(&e->ispec, &e->ospec)) & mask))
|
||||
chosen = i;
|
||||
}
|
||||
if (chosen != -1) mask &= cvtapply(c, &cvttab[chosen], &s);
|
||||
iter++;
|
||||
} while (chosen != -1);
|
||||
return (iter < 8)? chn_getcaps(c)->bestfmt : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
chn_addfeeder(pcm_channel *c, pcm_feeder *f)
|
||||
{
|
||||
pcm_feeder *n;
|
||||
n = malloc(sizeof(pcm_feeder), M_DEVBUF, M_NOWAIT);
|
||||
*n = *f;
|
||||
n->source = c->feeder;
|
||||
c->feeder = n;
|
||||
if (n->init) n->init(n);
|
||||
if (n->align > 0) c->align += n->align;
|
||||
else if (n->align < 0 && c->align < -n->align) c->align -= n->align;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chn_removefeeder(pcm_channel *c)
|
||||
{
|
||||
pcm_feeder *f;
|
||||
if (c->feeder == &feeder_root) return -1;
|
||||
|
||||
if (c->feeder->source == NULL)
|
||||
return -1;
|
||||
f = c->feeder->source;
|
||||
if (c->feeder->free) c->feeder->free(c->feeder);
|
||||
if (c->feeder->free)
|
||||
c->feeder->free(c->feeder);
|
||||
free(c->feeder, M_DEVBUF);
|
||||
c->feeder = f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chainok(pcm_feeder *test, pcm_feeder *stop)
|
||||
{
|
||||
u_int32_t visited[MAXFEEDERS / 32];
|
||||
u_int32_t idx, mask;
|
||||
|
||||
bzero(visited, sizeof(visited));
|
||||
while (test && (test != stop)) {
|
||||
idx = test->desc->idx;
|
||||
if (idx < 0)
|
||||
panic("bad idx %d", idx);
|
||||
if (idx >= MAXFEEDERS)
|
||||
panic("bad idx %d", idx);
|
||||
mask = 1 << (idx & 31);
|
||||
idx >>= 5;
|
||||
if (visited[idx] & mask)
|
||||
return 0;
|
||||
visited[idx] |= mask;
|
||||
test = test->source;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static pcm_feeder *
|
||||
feeder_fmtchain(u_int32_t *to, pcm_feeder *source, pcm_feeder *stop, int maxdepth)
|
||||
{
|
||||
struct feedertab_entry *fte;
|
||||
pcm_feeder *try, *ret;
|
||||
struct pcm_feederdesc *trydesc;
|
||||
|
||||
/* printf("trying %s...\n", source->name); */
|
||||
if (fmtvalid(source->desc->out, to)) {
|
||||
/* printf("got it\n"); */
|
||||
return source;
|
||||
}
|
||||
|
||||
if (maxdepth < 0)
|
||||
return NULL;
|
||||
|
||||
try = malloc(sizeof(*try), M_DEVBUF, M_NOWAIT);
|
||||
trydesc = malloc(sizeof(*trydesc), M_DEVBUF, M_NOWAIT);
|
||||
trydesc->type = FEEDER_FMT;
|
||||
trydesc->in = source->desc->out;
|
||||
trydesc->out = 0;
|
||||
trydesc->flags = 0;
|
||||
trydesc->idx = -1;
|
||||
|
||||
SLIST_FOREACH(fte, &feedertab, link) {
|
||||
if ((fte->desc) && (fte->desc->in == source->desc->out)) {
|
||||
*try = *(fte->feeder);
|
||||
try->source = source;
|
||||
try->desc = trydesc;
|
||||
trydesc->out = fte->desc->out;
|
||||
trydesc->idx = fte->idx;
|
||||
ret = chainok(try, stop)? feeder_fmtchain(to, try, stop, maxdepth - 1) : NULL;
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
free(try, M_DEVBUF);
|
||||
free(trydesc, M_DEVBUF);
|
||||
/* printf("giving up %s...\n", source->name); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
chn_feedchain(pcm_channel *c, u_int32_t *to)
|
||||
{
|
||||
pcm_feeder *try, *stop;
|
||||
int max;
|
||||
|
||||
stop = c->feeder;
|
||||
try = NULL;
|
||||
max = 0;
|
||||
while (try == NULL && max++ < 8)
|
||||
try = feeder_fmtchain(to, c->feeder, stop, max);
|
||||
if (try == NULL)
|
||||
return 0;
|
||||
c->feeder = try;
|
||||
c->align = 0;
|
||||
/* printf("chain: "); */
|
||||
while (try && (try != stop)) {
|
||||
/* printf("%s [%d]", try->name, try->desc->idx); */
|
||||
/* if (try->source) */
|
||||
/* printf(" -> "); */
|
||||
if (try->init)
|
||||
try->init(try);
|
||||
if (try->align > 0)
|
||||
c->align += try->align;
|
||||
else if (try->align < 0 && c->align < -try->align)
|
||||
c->align = -try->align;
|
||||
try = try->source;
|
||||
}
|
||||
/* printf("%s [%d]", try->name, try->desc->idx); */
|
||||
return c->feeder->desc->out;
|
||||
}
|
||||
|
36
sys/dev/sound/pcm/feeder.h
Normal file
36
sys/dev/sound/pcm/feeder.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
void feeder_register(void *p);
|
||||
pcm_feeder *feeder_get(struct pcm_feederdesc *desc);
|
||||
pcm_feeder *feeder_getroot(void);
|
||||
|
||||
u_int32_t chn_feedchain(pcm_channel *c, u_int32_t *to);
|
||||
int chn_removefeeder(pcm_channel *c);
|
||||
|
||||
|
@ -81,6 +81,7 @@ struct isa_device { int dummy; };
|
||||
|
||||
#include <dev/sound/pcm/datatypes.h>
|
||||
#include <dev/sound/pcm/channel.h>
|
||||
#include <dev/sound/pcm/feeder.h>
|
||||
#include <dev/sound/pcm/mixer.h>
|
||||
#include <dev/sound/pcm/dsp.h>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user