int yds_query_encoding(void *addr, struct audio_encoding *fp) { switch (fp->index) { case 0: strlcpy(fp->name, AudioEulinear, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR; fp->precision = 8; fp->flags = 0; break; case 1: strlcpy(fp->name, AudioEmulaw, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULAW; fp->precision = 8; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 2: strlcpy(fp->name, AudioEalaw, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ALAW; fp->precision = 8; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 3: strlcpy(fp->name, AudioEslinear, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR; fp->precision = 8; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 4: strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR_LE; fp->precision = 16; fp->flags = 0; break; case 5: strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR_LE; fp->precision = 16; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 6: strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR_BE; fp->precision = 16; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 7: strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR_BE; fp->precision = 16; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; default: return (EINVAL); } fp->bps = AUDIO_BPS(fp->precision); fp->msb = 1; return (0); }
/* Todo: don't commit settings to card until we've verified all parameters */ int neo_set_params(void *addr, int setmode, int usemode, struct audio_params *play, struct audio_params *rec) { struct neo_softc *sc = addr; u_int32_t base; u_int8_t x; int mode; struct audio_params *p; for (mode = AUMODE_RECORD; mode != -1; mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { if ((setmode & mode) == 0) continue; p = mode == AUMODE_PLAY ? play : rec; if (p == NULL) continue; for (x = 0; x < 8; x++) if (p->sample_rate < (samplerates[x] + samplerates[x + 1]) / 2) break; p->sample_rate = samplerates[x]; nm_loadcoeff(sc, mode, x); x <<= 4; x &= NM_RATE_MASK; if (p->precision == 16) x |= NM_RATE_BITS_16; if (p->channels == 2) x |= NM_RATE_STEREO; base = (mode == AUMODE_PLAY) ? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); switch (p->encoding) { case AUDIO_ENCODING_SLINEAR_LE: if (p->precision != 16) return EINVAL; break; case AUDIO_ENCODING_ULINEAR_LE: case AUDIO_ENCODING_ULINEAR_BE: if (p->precision != 8) return EINVAL; break; default: return (EINVAL); } p->bps = AUDIO_BPS(p->precision); p->msb = 1; } return (0); }
int yds_set_params(void *addr, int setmode, int usemode, struct audio_params *play, struct audio_params *rec) { struct audio_params *p; int mode; for (mode = AUMODE_RECORD; mode != -1; mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { if ((setmode & mode) == 0) continue; p = mode == AUMODE_PLAY ? play : rec; if (p->sample_rate < 4000) p->sample_rate = 4000; if (p->sample_rate > 48000) p->sample_rate = 48000; if (p->precision > 16) p->precision = 16; if (p->channels > 2) p->channels = 2; p->factor = 1; p->sw_code = 0; switch (p->encoding) { case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 16) p->sw_code = swap_bytes; else p->sw_code = change_sign8; break; case AUDIO_ENCODING_SLINEAR_LE: if (p->precision != 16) p->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_BE: if (p->precision == 16) { if (mode == AUMODE_PLAY) p->sw_code = swap_bytes_change_sign16_le; else p->sw_code = change_sign16_swap_bytes_le; } break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 16) p->sw_code = change_sign16_le; break; case AUDIO_ENCODING_ULAW: if (mode == AUMODE_PLAY) { p->factor = 2; p->precision = 16; p->sw_code = mulaw_to_slinear16_le; } else p->sw_code = ulinear8_to_mulaw; break; case AUDIO_ENCODING_ALAW: if (mode == AUMODE_PLAY) { p->factor = 2; p->precision = 16; p->sw_code = alaw_to_slinear16_le; } else p->sw_code = ulinear8_to_alaw; break; default: return (EINVAL); } p->bps = AUDIO_BPS(p->precision); p->msb = 1; } return 0; }
int auvia_set_params(void *addr, int setmode, int usemode, struct audio_params *play, struct audio_params *rec) { struct auvia_softc *sc = addr; struct auvia_softc_chan *ch; struct audio_params *p; struct ac97_codec_if* codec = sc->codec_if; int reg, mode; u_int16_t ext_id; /* for mode in (RECORD, PLAY) */ for (mode = AUMODE_RECORD; mode != -1; mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { if ((setmode & mode) == 0) continue; if (mode == AUMODE_PLAY) { p = play; ch = &sc->sc_play; reg = AC97_REG_PCM_FRONT_DAC_RATE; } else { p = rec; ch = &sc->sc_record; reg = AC97_REG_PCM_LR_ADC_RATE; } if (ch->sc_base == VIA8233_MP_BASE && mode == AUMODE_PLAY) { ext_id = codec->vtbl->get_caps(codec); if (p->channels == 1) { /* ok */ } else if (p->channels == 2) { /* ok */ } else if (p->channels == 4 && ext_id & AC97_EXT_AUDIO_SDAC) { /* ok */ } else if (p->channels == 6 && (ext_id & AC97_BITS_6CH) == AC97_BITS_6CH) { /* ok */ } else { p->channels = 2; } } else { if (p->channels > 2) p->channels = 2; } if (p->sample_rate < 4000) p->sample_rate = 4000; if (p->sample_rate > 48000) p->sample_rate = 48000; if (p->precision > 16) p->precision = 16; /* XXX only 16-bit 48kHz slinear_le if s/pdif enabled ? */ if (sc->sc_spdif) { p->sample_rate = 48000; p->precision = 16; p->encoding = AUDIO_ENCODING_SLINEAR_LE; } /* XXX only 16-bit 48kHz slinear_le if s/pdif enabled ? */ if (sc->sc_spdif && ((p->sample_rate != 48000) || (p->precision != 16) || (p->encoding != AUDIO_ENCODING_SLINEAR_LE))) return (EINVAL); if (AC97_IS_FIXED_RATE(codec)) { p->sample_rate = AC97_SINGLE_RATE; } else { if (codec->vtbl->set_rate(codec, reg, &p->sample_rate)) return (EINVAL); if (ch->sc_base == VIA8233_MP_BASE && mode == AUMODE_PLAY) { reg = AC97_REG_PCM_SURR_DAC_RATE; if (p->channels >= 4 && codec->vtbl->set_rate(codec, reg, &p->sample_rate)) return (EINVAL); reg = AC97_REG_PCM_LFE_DAC_RATE; if (p->channels == 6 && codec->vtbl->set_rate(codec, reg, &p->sample_rate)) return (EINVAL); } } p->factor = 1; p->sw_code = 0; switch (p->encoding) { case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 16) p->sw_code = swap_bytes; else p->sw_code = change_sign8; break; case AUDIO_ENCODING_SLINEAR_LE: if (p->precision != 16) p->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_BE: if (p->precision == 16) p->sw_code = mode == AUMODE_PLAY? swap_bytes_change_sign16_le : change_sign16_swap_bytes_le; break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 16) p->sw_code = change_sign16_le; break; case AUDIO_ENCODING_ULAW: if (mode == AUMODE_PLAY) { p->factor = 2; p->sw_code = mulaw_to_slinear16_le; } else p->sw_code = ulinear8_to_mulaw; break; case AUDIO_ENCODING_ALAW: if (mode == AUMODE_PLAY) { p->factor = 2; p->sw_code = alaw_to_slinear16_le; } else p->sw_code = ulinear8_to_alaw; break; case AUDIO_ENCODING_SLINEAR: case AUDIO_ENCODING_ULINEAR: break; default: return (EINVAL); } auvia_set_params_sub(sc, ch, p); p->bps = AUDIO_BPS(p->precision); p->msb = 1; } return 0; }
int ad1848_set_params(void *addr, int setmode, int usemode, struct audio_params *p, struct audio_params *r) { struct ad1848_softc *sc = addr; int error, bits, enc; void (*pswcode)(void *, u_char *buf, int cnt); void (*rswcode)(void *, u_char *buf, int cnt); DPRINTF(("ad1848_set_params: %d %d %d %ld\n", p->encoding, p->precision, p->channels, p->sample_rate)); enc = p->encoding; pswcode = rswcode = 0; switch (enc) { case AUDIO_ENCODING_SLINEAR_LE: if (p->precision == 8) { enc = AUDIO_ENCODING_ULINEAR_LE; pswcode = rswcode = change_sign8; } break; case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 16 && sc->mode == 1) { enc = AUDIO_ENCODING_SLINEAR_LE; pswcode = rswcode = swap_bytes; } break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 16) { enc = AUDIO_ENCODING_SLINEAR_LE; pswcode = rswcode = change_sign16_le; } break; case AUDIO_ENCODING_ULINEAR_BE: if (p->precision == 16) { enc = AUDIO_ENCODING_SLINEAR_LE; pswcode = swap_bytes_change_sign16_le; rswcode = change_sign16_swap_bytes_le; } break; } switch (enc) { case AUDIO_ENCODING_ULAW: bits = FMT_ULAW; break; case AUDIO_ENCODING_ALAW: bits = FMT_ALAW; break; case AUDIO_ENCODING_ADPCM: bits = FMT_ADPCM; break; case AUDIO_ENCODING_SLINEAR_LE: if (p->precision == 16) bits = FMT_TWOS_COMP; else return EINVAL; break; case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 16) bits = FMT_TWOS_COMP_BE; else return EINVAL; break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 8) bits = FMT_PCM8; else return EINVAL; break; default: return EINVAL; } if (p->channels < 1 || p->channels > 2) return EINVAL; error = ad1848_set_speed(sc, &p->sample_rate); if (error) return error; p->sw_code = pswcode; r->sw_code = rswcode; p->bps = AUDIO_BPS(p->precision); r->bps = AUDIO_BPS(r->precision); p->msb = 1; r->msb = 1; sc->format_bits = bits; sc->channels = p->channels; sc->precision = p->precision; sc->need_commit = 1; DPRINTF(("ad1848_set_params succeeded, bits=%x\n", bits)); return (0); }
int ad1848_query_encoding(void *addr, struct audio_encoding *fp) { struct ad1848_softc *sc = addr; switch (fp->index) { case 0: strlcpy(fp->name, AudioEmulaw, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULAW; fp->precision = 8; fp->flags = 0; break; case 1: strlcpy(fp->name, AudioEalaw, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ALAW; fp->precision = 8; fp->flags = 0; break; case 2: strlcpy(fp->name, AudioEslinear_le, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR_LE; fp->precision = 16; fp->flags = 0; break; case 3: strlcpy(fp->name, AudioEulinear, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR; fp->precision = 8; fp->flags = 0; break; case 4: /* only on CS4231 */ strlcpy(fp->name, AudioEslinear_be, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR_BE; fp->precision = 16; fp->flags = sc->mode == 1 ? AUDIO_ENCODINGFLAG_EMULATED : 0; break; /* emulate some modes */ case 5: strlcpy(fp->name, AudioEslinear, sizeof fp->name); fp->encoding = AUDIO_ENCODING_SLINEAR; fp->precision = 8; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 6: strlcpy(fp->name, AudioEulinear_le, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR_LE; fp->precision = 16; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 7: strlcpy(fp->name, AudioEulinear_be, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ULINEAR_BE; fp->precision = 16; fp->flags = AUDIO_ENCODINGFLAG_EMULATED; break; case 8: /* only on CS4231 */ if (sc->mode == 1) return EINVAL; strlcpy(fp->name, AudioEadpcm, sizeof fp->name); fp->encoding = AUDIO_ENCODING_ADPCM; fp->precision = 8; fp->flags = 0; break; default: return EINVAL; /*NOTREACHED*/ } fp->bps = AUDIO_BPS(fp->precision); fp->msb = 1; return (0); }
int fms_set_params(void *addr, int setmode, int usemode, struct audio_params *play, struct audio_params *rec) { struct fms_softc *sc = addr; int i; if (setmode & AUMODE_PLAY) { play->factor = 1; play->sw_code = 0; switch(play->encoding) { case AUDIO_ENCODING_ULAW: play->factor = 2; play->sw_code = mulaw_to_slinear16_le; break; case AUDIO_ENCODING_SLINEAR_LE: if (play->precision == 8) play->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_LE: if (play->precision == 16) play->sw_code = change_sign16_le; break; case AUDIO_ENCODING_ALAW: play->factor = 2; play->sw_code = alaw_to_slinear16_le; break; case AUDIO_ENCODING_SLINEAR_BE: if (play->precision == 16) play->sw_code = swap_bytes; else play->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_BE: if (play->precision == 16) play->sw_code = change_sign16_swap_bytes_le; break; default: return EINVAL; } play->bps = AUDIO_BPS(play->precision); play->msb = 1; for (i = 0; i < 10 && play->sample_rate > fms_rates[i].limit; i++) ; play->sample_rate = fms_rates[i].rate; sc->sc_play_reg = (play->channels == 2 ? FM_PLAY_STEREO : 0) | (play->precision * play->factor == 16 ? FM_PLAY_16BIT : 0) | (i << 8); } if (setmode & AUMODE_RECORD) { rec->factor = 1; rec->sw_code = 0; switch(rec->encoding) { case AUDIO_ENCODING_ULAW: rec->sw_code = ulinear8_to_mulaw; break; case AUDIO_ENCODING_SLINEAR_LE: if (rec->precision == 8) rec->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_LE: if (rec->precision == 16) rec->sw_code = change_sign16_le; break; case AUDIO_ENCODING_ALAW: rec->sw_code = ulinear8_to_alaw; break; case AUDIO_ENCODING_SLINEAR_BE: if (rec->precision == 16) rec->sw_code = swap_bytes; else rec->sw_code = change_sign8; break; case AUDIO_ENCODING_ULINEAR_BE: if (rec->precision == 16) rec->sw_code = swap_bytes_change_sign16_le; break; default: return EINVAL; } rec->bps = AUDIO_BPS(rec->precision); rec->msb = 1; for (i = 0; i < 10 && rec->sample_rate > fms_rates[i].limit; i++) ; rec->sample_rate = fms_rates[i].rate; sc->sc_rec_reg = (rec->channels == 2 ? FM_REC_STEREO : 0) | (rec->precision * rec->factor == 16 ? FM_REC_16BIT : 0) | (i << 8); } return 0; }