📄 bsd_audio.c
字号:
} return (1);}#endif/* ARGSUSED */intaudioswintr(sc0) void *sc0;{ register struct audio_softc *sc; register int s, ret = 0;#ifdef SUNOS sc = &audio_softc;#else sc = sc0;#endif s = splaudio(); if (sc->sc_au.au_rb.cb_waking != 0) { sc->sc_au.au_rb.cb_waking = 0; splx(s); ret = 1; wakeup((caddr_t)&sc->sc_au.au_rb); SELWAKEUP(&sc->sc_rsel); } if (sc->sc_au.au_wb.cb_waking != 0) { sc->sc_au.au_wb.cb_waking = 0; splx(s); ret = 1; wakeup((caddr_t)&sc->sc_au.au_wb); SELWAKEUP(&sc->sc_wsel); } else splx(s); return (ret);}/* Write 16 bits of data from variable v to the data port of the audio chip */#define WAMD16(amd, v) ((amd)->dr = (v), (amd)->dr = (v) >> 8)voidaudio_setmap(amd, map) register volatile struct amd7930 *amd; register struct mapreg *map;{ register int i, s, v; s = splaudio(); amd->cr = AMDR_MAP_1_10; for (i = 0; i < 8; i++) { v = map->mr_x[i]; WAMD16(amd, v); } for (i = 0; i < 8; ++i) { v = map->mr_r[i]; WAMD16(amd, v); } v = map->mr_gx; WAMD16(amd, v); v = map->mr_gr; WAMD16(amd, v); v = map->mr_ger; WAMD16(amd, v); v = map->mr_stgr; WAMD16(amd, v); v = map->mr_ftgr; WAMD16(amd, v); v = map->mr_atgr; WAMD16(amd, v); amd->dr = map->mr_mmr1; amd->dr = map->mr_mmr2; splx(s);}/* * Set the mmr1 register and one other 16 bit register in the audio chip. * The other register is indicated by op and val. */voidaudio_setmmr1(amd, mmr1, op, val) register volatile struct amd7930 *amd; register int mmr1; register int op; register int val;{ register int s = splaudio(); amd->cr = AMDR_MAP_MMR1; amd->dr = mmr1; amd->cr = op; WAMD16(amd, val); splx(s);}/* * Set the mmr2 register. */static voidaudio_setmmr2(amd, mmr2) register volatile struct amd7930 *amd; register int mmr2;{ register int s = splaudio(); amd->cr = AMDR_MAP_MMR2; amd->dr = mmr2; splx(s);}/* * gx, gr & stg gains. this table must contain 256 elements with * the 0th being "infinity" (the magic value 9008). The remaining * elements match sun's gain curve (but with higher resolution): * -18 to 0dB in .16dB steps then 0 to 12dB in .08dB steps. */static const u_short gx_coeff[256] = { 0x9008, 0x8b7c, 0x8b51, 0x8b45, 0x8b42, 0x8b3b, 0x8b36, 0x8b33, 0x8b32, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b25, 0x8b23, 0x8b22, 0x8b22, 0x9122, 0x8b1a, 0x8aa3, 0x8aa3, 0x8b1c, 0x8aa6, 0x912d, 0x912b, 0x8aab, 0x8b12, 0x8aaa, 0x8ab2, 0x9132, 0x8ab4, 0x913c, 0x8abb, 0x9142, 0x9144, 0x9151, 0x8ad5, 0x8aeb, 0x8a79, 0x8a5a, 0x8a4a, 0x8b03, 0x91c2, 0x91bb, 0x8a3f, 0x8a33, 0x91b2, 0x9212, 0x9213, 0x8a2c, 0x921d, 0x8a23, 0x921a, 0x9222, 0x9223, 0x922d, 0x9231, 0x9234, 0x9242, 0x925b, 0x92dd, 0x92c1, 0x92b3, 0x92ab, 0x92a4, 0x92a2, 0x932b, 0x9341, 0x93d3, 0x93b2, 0x93a2, 0x943c, 0x94b2, 0x953a, 0x9653, 0x9782, 0x9e21, 0x9d23, 0x9cd2, 0x9c23, 0x9baa, 0x9bde, 0x9b33, 0x9b22, 0x9b1d, 0x9ab2, 0xa142, 0xa1e5, 0x9a3b, 0xa213, 0xa1a2, 0xa231, 0xa2eb, 0xa313, 0xa334, 0xa421, 0xa54b, 0xada4, 0xac23, 0xab3b, 0xaaab, 0xaa5c, 0xb1a3, 0xb2ca, 0xb3bd, 0xbe24, 0xbb2b, 0xba33, 0xc32b, 0xcb5a, 0xd2a2, 0xe31d, 0x0808, 0x72ba, 0x62c2, 0x5c32, 0x52db, 0x513e, 0x4cce, 0x43b2, 0x4243, 0x41b4, 0x3b12, 0x3bc3, 0x3df2, 0x34bd, 0x3334, 0x32c2, 0x3224, 0x31aa, 0x2a7b, 0x2aaa, 0x2b23, 0x2bba, 0x2c42, 0x2e23, 0x25bb, 0x242b, 0x240f, 0x231a, 0x22bb, 0x2241, 0x2223, 0x221f, 0x1a33, 0x1a4a, 0x1acd, 0x2132, 0x1b1b, 0x1b2c, 0x1b62, 0x1c12, 0x1c32, 0x1d1b, 0x1e71, 0x16b1, 0x1522, 0x1434, 0x1412, 0x1352, 0x1323, 0x1315, 0x12bc, 0x127a, 0x1235, 0x1226, 0x11a2, 0x1216, 0x0a2a, 0x11bc, 0x11d1, 0x1163, 0x0ac2, 0x0ab2, 0x0aab, 0x0b1b, 0x0b23, 0x0b33, 0x0c0f, 0x0bb3, 0x0c1b, 0x0c3e, 0x0cb1, 0x0d4c, 0x0ec1, 0x079a, 0x0614, 0x0521, 0x047c, 0x0422, 0x03b1, 0x03e3, 0x0333, 0x0322, 0x031c, 0x02aa, 0x02ba, 0x02f2, 0x0242, 0x0232, 0x0227, 0x0222, 0x021b, 0x01ad, 0x0212, 0x01b2, 0x01bb, 0x01cb, 0x01f6, 0x0152, 0x013a, 0x0133, 0x0131, 0x012c, 0x0123, 0x0122, 0x00a2, 0x011b, 0x011e, 0x0114, 0x00b1, 0x00aa, 0x00b3, 0x00bd, 0x00ba, 0x00c5, 0x00d3, 0x00f3, 0x0062, 0x0051, 0x0042, 0x003b, 0x0033, 0x0032, 0x002a, 0x002c, 0x0025, 0x0023, 0x0022, 0x001a, 0x0021, 0x001b, 0x001b, 0x001d, 0x0015, 0x0013, 0x0013, 0x0012, 0x0012, 0x000a, 0x000a, 0x0011, 0x0011, 0x000b, 0x000b, 0x000c, 0x000e,};/* * second stage play gain. */static const u_short ger_coeff[] = { 0x431f, /* 5. dB */ 0x331f, /* 5.5 dB */ 0x40dd, /* 6. dB */ 0x11dd, /* 6.5 dB */ 0x440f, /* 7. dB */ 0x411f, /* 7.5 dB */ 0x311f, /* 8. dB */ 0x5520, /* 8.5 dB */ 0x10dd, /* 9. dB */ 0x4211, /* 9.5 dB */ 0x410f, /* 10. dB */ 0x111f, /* 10.5 dB */ 0x600b, /* 11. dB */ 0x00dd, /* 11.5 dB */ 0x4210, /* 12. dB */ 0x110f, /* 13. dB */ 0x7200, /* 14. dB */ 0x2110, /* 15. dB */ 0x2200, /* 15.9 dB */ 0x000b, /* 16.9 dB */ 0x000f /* 18. dB */#define NGER (sizeof(ger_coeff) / sizeof(ger_coeff[0]))};static voidausetrgain(sc, level) register struct audio_softc *sc; register int level;{ level &= 0xff; sc->sc_rlevel = level; sc->sc_map.mr_mmr1 |= AMD_MMR1_GX; sc->sc_map.mr_gx = gx_coeff[level]; audio_setmmr1(sc->sc_au.au_amd, sc->sc_map.mr_mmr1, AMDR_MAP_GX, sc->sc_map.mr_gx);}static voidausetpgain(sc, level) register struct audio_softc *sc; register int level;{ register int gi, s; register volatile struct amd7930 *amd; level &= 0xff; sc->sc_plevel = level; sc->sc_map.mr_mmr1 |= AMD_MMR1_GER|AMD_MMR1_GR; level *= 256 + NGER; level >>= 8; if (level >= 256) { gi = level - 256; level = 255; } else gi = 0; sc->sc_map.mr_ger = ger_coeff[gi]; sc->sc_map.mr_gr = gx_coeff[level]; amd = sc->sc_au.au_amd; s = splaudio(); amd->cr = AMDR_MAP_MMR1; amd->dr = sc->sc_map.mr_mmr1; amd->cr = AMDR_MAP_GR; gi = sc->sc_map.mr_gr; WAMD16(amd, gi); amd->cr = AMDR_MAP_GER; gi = sc->sc_map.mr_ger; WAMD16(amd, gi); splx(s);}static voidausetmgain(sc, level) register struct audio_softc *sc; register int level;{ level &= 0xff; sc->sc_mlevel = level; sc->sc_map.mr_mmr1 |= AMD_MMR1_STG; sc->sc_map.mr_stgr = gx_coeff[level]; audio_setmmr1(sc->sc_au.au_amd, sc->sc_map.mr_mmr1, AMDR_MAP_STG, sc->sc_map.mr_stgr);}static intaudiosetinfo(sc, ai) struct audio_softc *sc; struct audio_info *ai;{ struct audio_prinfo *r = &ai->record, *p = &ai->play; register int s, bsize; if (p->gain != ~0) ausetpgain(sc, p->gain); if (r->gain != ~0) ausetrgain(sc, r->gain); if (ai->monitor_gain != ~0) ausetmgain(sc, ai->monitor_gain); if (p->port == AUDIO_SPEAKER) { sc->sc_map.mr_mmr2 |= AMD_MMR2_LS; audio_setmmr2(sc->sc_au.au_amd, sc->sc_map.mr_mmr2); } else if (p->port == AUDIO_HEADPHONE) { sc->sc_map.mr_mmr2 &=~ AMD_MMR2_LS; audio_setmmr2(sc->sc_au.au_amd, sc->sc_map.mr_mmr2); } if (p->pause != (u_char)~0) sc->sc_au.au_wb.cb_pause = p->pause; if (r->pause != (u_char)~0) sc->sc_au.au_rb.cb_pause = r->pause; if (ai->blocksize != ~0) { if (ai->blocksize == 0) bsize = ai->blocksize = DEFBLKSIZE; else if (ai->blocksize > MAXBLKSIZE) bsize = ai->blocksize = MAXBLKSIZE; else bsize = ai->blocksize; s = splaudio(); sc->sc_au.au_blksize = bsize; /* AUDIO_FLUSH */ AUCB_INIT(&sc->sc_au.au_rb); AUCB_INIT(&sc->sc_au.au_wb); splx(s); } if (ai->hiwat != ~0 && (unsigned)ai->hiwat < AUCB_SIZE) sc->sc_au.au_hiwat = ai->hiwat; if (ai->lowat != ~0 && ai->lowat < AUCB_SIZE) sc->sc_au.au_lowat = ai->lowat; if (ai->backlog != ~0 && ai->backlog < (AUCB_SIZE/2)) sc->sc_au.au_backlog = ai->backlog; return (0);}static intsunaudiosetinfo(sc, ai) struct audio_softc *sc; struct sun_audio_info *ai;{ struct sun_audio_prinfo *r = &ai->record, *p = &ai->play; if (p->gain != ~0) ausetpgain(sc, p->gain); if (r->gain != ~0) ausetrgain(sc, r->gain); if (ai->monitor_gain != ~0) ausetmgain(sc, ai->monitor_gain); if (p->port == AUDIO_SPEAKER) { sc->sc_map.mr_mmr2 |= AMD_MMR2_LS; audio_setmmr2(sc->sc_au.au_amd, sc->sc_map.mr_mmr2); } else if (p->port == AUDIO_HEADPHONE) { sc->sc_map.mr_mmr2 &=~ AMD_MMR2_LS; audio_setmmr2(sc->sc_au.au_amd, sc->sc_map.mr_mmr2); } /* * The bsd driver does not distinguish between paused and active. * (In the sun driver, not active means samples are not ouput * at all, but paused means the last streams buffer is drained * and then output stops.) If either are 0, then when stop output. * Otherwise, if either are non-zero, we resume. */ if (p->pause == 0 || p->active == 0) sc->sc_au.au_wb.cb_pause = 0; else if (p->pause != (u_char)~0 || p->active != (u_char)~0) sc->sc_au.au_wb.cb_pause = 1; if (r->pause == 0 || r->active == 0) sc->sc_au.au_rb.cb_pause = 0; else if (r->pause != (u_char)~0 || r->active != (u_char)~0) sc->sc_au.au_rb.cb_pause = 1; return (0);}static intaudiogetinfo(sc, ai) struct audio_softc *sc; struct audio_info *ai;{ struct audio_prinfo *r = &ai->record, *p = &ai->play; p->sample_rate = r->sample_rate = 8000; p->channels = r->channels = 1; p->precision = r->precision = 8; p->encoding = r->encoding = AUDIO_ENCODING_ULAW; ai->monitor_gain = sc->sc_mlevel; r->gain = sc->sc_rlevel; p->gain = sc->sc_plevel; r->port = 1; p->port = (sc->sc_map.mr_mmr2 & AMD_MMR2_LS) ? AUDIO_SPEAKER : AUDIO_HEADPHONE; p->pause = sc->sc_au.au_wb.cb_pause; r->pause = sc->sc_au.au_rb.cb_pause; p->error = sc->sc_au.au_wb.cb_drops != 0; r->error = sc->sc_au.au_rb.cb_drops != 0; p->open = sc->sc_open; r->open = sc->sc_open; p->samples = sc->sc_au.au_stamp - sc->sc_au.au_wb.cb_pdrops; r->samples = sc->sc_au.au_stamp - sc->sc_au.au_rb.cb_pdrops; p->seek = sc->sc_wseek; r->seek = sc->sc_rseek; ai->blocksize = sc->sc_au.au_blksize; ai->hiwat = sc->sc_au.au_hiwat; ai->lowat = sc->sc_au.au_lowat; ai->backlog = sc->sc_au.au_backlog; return (0);}static intsunaudiogetinfo(sc, ai) struct audio_softc *sc; struct sun_audio_info *ai;{ struct sun_audio_prinfo *r = &ai->record, *p = &ai->play; p->sample_rate = r->sample_rate = 8000; p->channels = r->channels = 1; p->precision = r->precision = 8; p->encoding = r->encoding = AUDIO_ENCODING_ULAW; ai->monitor_gain = sc->sc_mlevel; r->gain = sc->sc_rlevel; p->gain = sc->sc_plevel; r->port = 1; p->port = (sc->sc_map.mr_mmr2 & AMD_MMR2_LS) ? AUDIO_SPEAKER : AUDIO_HEADPHONE; p->active = p->pause = sc->sc_au.au_wb.cb_pause; r->active = r->pause = sc->sc_au.au_rb.cb_pause; p->error = sc->sc_au.au_wb.cb_drops != 0; r->error = sc->sc_au.au_rb.cb_drops != 0; p->waiting = 0; r->waiting = 0; p->eof = 0; r->eof = 0; p->open = sc->sc_open; r->open = sc->sc_open; p->samples = sc->sc_au.au_stamp - sc->sc_au.au_wb.cb_pdrops; r->samples = sc->sc_au.au_stamp - sc->sc_au.au_rb.cb_pdrops; return (0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -