Subject: kern/20620: add emuxki support for recording formats
To: None <gnats-bugs@gnats.netbsd.org>
From: None <yh@metroweb.co.za>
List: netbsd-bugs
Date: 03/08/2003 16:42:40
>Number: 20620
>Category: kern
>Synopsis: add additional formats for emuxki recording
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sat Mar 08 06:44:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Yorick Hardy
>Release: NetBSD 1.6_STABLE
>Organization:
>Environment:
System: NetBSD Yorick 1.6_STABLE NetBSD 1.6_STABLE (YORICK) #277: Sat Mar 8 14:53:36 SAST 2003 yorick@Yorick:/usr/src/sys/arch/i386/compile/YORICK i386
Architecture: i386
Machine: i386
>Description:
The emu10k1 only supports 16 bit signed linear format, so add software
conversion for other recording formats.
>How-To-Repeat:
Not applicable.
>Fix:
Apply the following patch (against revision 1.20 of emuxki.c).
Also remove the comment about single source recording as it is now supported.
--- sys/dev/pci/emuxki.c.orig Sat Mar 8 14:08:17 2003
+++ sys/dev/pci/emuxki.c Sat Mar 8 14:50:51 2003
@@ -49,7 +49,6 @@
* TODO:
* - Digital Outputs
* - (midi/mpu),joystick support
- * - Single source recording
* - Multiple voices play (problem with /dev/audio architecture)
* - Multiple sources recording (Pb with audio(4))
* - Independant modification of each channel's parameters (via mixer ?)
@@ -1524,10 +1523,6 @@
voice->dataloc.chan[0]->loop.start);
else
/* returns number of bytes */
- /*
- * XXX Linux driver suggests something special is needed
- * XXX when precision == 8.
- */
return (emuxki_read(voice->sc, 0,
emuxki_recsrc_idxreg[voice->dataloc.source]) &
EMU_RECIDX_MASK);
@@ -1839,10 +1834,22 @@
mode = (voice->use & EMU_VOICE_USE_PLAY) ?
AUMODE_PLAY : AUMODE_RECORD;
p->factor = 1;
+ p->factor_denom = 1;
p->sw_code = NULL;
if (p->channels != 1 && p->channels != 2)
return (EINVAL);/* Will change when streams come in use */
+ if (mode == AUMODE_RECORD)
+ {
+ if (emuxki_recsrc_rate_to_index(p->sample_rate) < 0)
+ return (EINVAL);
+ p->hw_sample_rate = p->sample_rate;
+ p->hw_channels = p->channels;
+ p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
+ p->hw_precision = 16;
+ b16 = 1;
+ }
+
switch (p->encoding) {
case AUDIO_ENCODING_ULAW:
if (mode == AUMODE_PLAY) {
@@ -1850,8 +1857,8 @@
p->sw_code = mulaw_to_slinear16_le;
b16 = 1;
} else {
- p->sw_code = ulinear8_to_mulaw;
- b16 = 0;
+ p->factor = 2;
+ p->sw_code = slinear16_to_mulaw_le;
}
break;
@@ -1861,39 +1868,69 @@
p->sw_code = alaw_to_slinear16_le;
b16 = 1;
} else {
- p->sw_code = ulinear8_to_alaw;
- b16 = 0;
+ p->factor = 2;
+ p->sw_code = slinear16_to_alaw_le;
}
break;
case AUDIO_ENCODING_SLINEAR_LE:
- if (p->precision == 8)
- p->sw_code = change_sign8;
- b16 = (p->precision == 16);
+ if (mode == AUMODE_PLAY) {
+ if (p->precision == 8)
+ p->sw_code = change_sign8;
+ b16 = (p->precision == 16);
+ } else {
+ if (p->precision == 8) {
+ p->factor = 2;
+ p->sw_code = linear16_to_linear8_le;
+ }
+ }
break;
case AUDIO_ENCODING_ULINEAR_LE:
- if (p->precision == 16)
- p->sw_code = change_sign16_le;
- b16 = (p->precision == 16);
+ if (mode == AUMODE_PLAY) {
+ if (p->precision == 16)
+ p->sw_code = change_sign16_le;
+ b16 = (p->precision == 16);
+ } else {
+ if (p->precision == 8) {
+ p->factor = 2;
+ p->sw_code = slinear16_to_ulinear8_le;
+ }
+ else
+ p->sw_code = change_sign16_le;
+ }
break;
case AUDIO_ENCODING_SLINEAR_BE:
- if (p->precision == 16)
- p->sw_code = swap_bytes;
- else
- p->sw_code = change_sign8;
- b16 = (p->precision == 16);
+ if (mode == AUMODE_PLAY) {
+ if (p->precision == 16)
+ p->sw_code = swap_bytes;
+ else
+ p->sw_code = change_sign8;
+ b16 = (p->precision == 16);
+ } else {
+ if (p->precision == 8) {
+ p->factor = 2;
+ p->sw_code = linear16_to_linear8_le;
+ }
+ else
+ p->sw_code = swap_bytes;
+ }
break;
case AUDIO_ENCODING_ULINEAR_BE:
- if (p->precision == 16) {
- if (mode == AUMODE_PLAY)
+ if (mode == AUMODE_PLAY) {
+ if (p->precision == 16)
p->sw_code = swap_bytes_change_sign16_le;
+ b16 = (p->precision == 16);
+ } else {
+ if (p->precision == 8) {
+ p->factor = 2;
+ p->sw_code = slinear16_to_ulinear8_le;
+ }
else
p->sw_code = change_sign16_swap_bytes_le;
}
- b16 = (p->precision == 16);
break;
default:
>Release-Note:
>Audit-Trail:
>Unformatted: