Example #1
0
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);
}
Example #2
0
File: neo.c Project: bluhm/sys
/* 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);
}
Example #3
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;
}
Example #4
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;
}
Example #5
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);
}
Example #6
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);
}
Example #7
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;
}