¡Obsoleto

Soporte ALSA para el Bt878a

English Version

Componentes:

Fedora Core 2
Linux Kernel 2.6.5
ALSA 1.0.6a

 

Preparación

Linux recién instalado. Cargamos los módulos para la tarjeta de sonido SoundBlaster y el ADC del Bt878:

# modprobe snd-sb16
# modprobe snd-bt87x


Comprobamos que se han cargado:

# lsmod

Module                  Size  Used by
snd_bt87x              11720  0 
snd_mixer_oss          17664  2 
snd_sb16               12620  4 
snd_opl3_lib            9472  1 snd_sb16
snd_hwdep               9220  1 snd_opl3_lib
snd_sb16_dsp            8576  1 snd_sb16
snd_sb_common          13696  2 snd_sb16,snd_sb16_dsp
snd_pcm                75144  2 snd_bt87x,snd_sb16_dsp
snd_timer              21636  2 snd_opl3_lib,snd_pcm
snd_page_alloc          9224  2 snd_bt87x,snd_pcm
snd_mpu401_uart         6784  1 snd_sb16
snd_rawmidi            21156  1 snd_mpu401_uart
snd_seq_device          7816  2 snd_opl3_lib,snd_rawmidi
snd                    46724  16 snd_bt87x,snd_mixer_oss,snd_sb16,snd_opl3_lib,snd_hwdep,snd_sb16_dsp,snd_sb_common,snd_pcm,snd_timer,snd_mpu401_uart,snd_rawmidi,snd_seq_device
soundcore               6112  3 snd
autofs4                10880  0 
ne2k_pci                7136  0 
8390                    6912  1 ne2k_pci
floppy                 47952  0 
sg                     28192  0 
scsi_mod               91984  1 sg
dm_mod                 33312  0 
ipv6                  186080  6 
ext3                  102248  2 
jbd                    40216  1 ext3


Mezclador

Instalamos el gnome-alsamixer. Parece ser que el mezclador incluido en el Fedora Core 2 conecta con el mixer OSS emulado y no con el nativo ALSA. (?)

Página oficial gnome-alsamixer http://www.paw.co.za/projects/gnome-alsamixer/ . Tienen problemas en su servicio FTP. Finalmente he obtenido la versión 0.9.3 de aquí: http://prdownloads.sourceforge.net/dropline-gnome/gnome-alsamixer-0.9.3.tar.bz2?download .

Descomprimimos, configuramos, compilamos e instalamos.

# cd gnome-alsamixer-0.9.3
# ./configure
# make
# make install
# gnome-alsamixer

gnome-alsa-mixer-bt87x

Subimos el volumen al máximo (como indica la imagen).
 

¡Obsoleto


Captura de prueba (1)

Realizamos una captura de prueba utilizando el comando arecord nativo de ALSA:

# arecord -D hw:1,1 -f S16_LE -t wav test.wav

-D hw:1,1    1 es el segundo periférico físico (el primero es el 0, en mi caso la SoundBlaster) y 1 es el segundo periférico lógico (el primero es el 0, la interfase digital del Bt878a)
-f S16_LE    Formato "signed word little-endian"

Aparecen los siguientes mensajes de error en /var/log/messages:

Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xb8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 22 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xb8008008, PCI status 0x290
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xc8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 3 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xd8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 23 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xd8008808, PCI status 0x8290
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xd8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 2 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xe8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 13 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0xf8008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 13 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0x8008008, PCI status 0x8290
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0x8008008, PCI status 0x8290
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0x18008008, PCI status 0x8290
Oct  3 16:18:49 lab last message repeated 18 times
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0x18008008, PCI status 0x290
Oct  3 16:18:49 lab kernel: Aieee - PCI error! status 0x18008008, PCI status 0x8290

 

No entiendo el motivo de estos mensajes de error. Este mismo hardware bajo OSS funciona correctamente.

Se lo explico en un email a Clemens Ladisch (creador del modulo bt87x) y muy amablemente me contesta:

"... "PCI status 8xxx" means that there was a parity error, i.e., some
data on the PCI bus was corrupted. This is a hardware problem. The
OSS driver silently ignores such errors.
If you want the same behaviour with the ALSA driver, remove the lines
    if (chip->reg_control & CTL_ACAP_EN)
    snd_pcm_stop(chip->substream, SNDRV_PCM_STATE_XRUN);
from the bt87x.c file, and remove the "else" in the next line ..."

 

¡Obsoleto

 

Actualización versión ALSA

Obtención de ficheros. Descargo la última versión estable de aquí: http://www.alsa-project.org/ . Descargo: alsa-driver-1.0.6a.tar.bz2, alsa-lib-1.0.6.tar.bz2, alsa-utils-1.0.6.tar.bz2 y alsa-oss-1.0.6.tar.bz2

# cd alsa-lib-1.0.6
# ./configure
# make
# make install

# cd alsa-driver-1.0.6a
# ./configure --with-cards=sb16,bt87x
# make
# make install

# cd alsa-utils-1.0.6
# ./configure
# make
# make install

# cd alsa-oss-1.0.6
# ./configure
# make
# make install

Ejecutamos alsaconf:

# cd
# alsaconf

Pero en mi caso este comando no detectó el ADC del Bt878a. Visualizamos el contenido del fichero /etc/modprobe.conf:

# cat /etc/modprobe.conf

alias eth0 ne2k-pci
alias char-major-81 bttv
# --- BEGIN: Generated by ALSACONF, do not edit. ---
# --- ALSACONF verion 1.0.6 ---
alias snd-card-0 snd-sb16
alias sound-slot-0 snd-sb16
options snd-sb16 isapnp=0
# --- END: Generated by ALSACONF, do not edit. ---


Y añadimos las siguientes líneas al final del fichero:

alias snd-card-1 snd-bt87x
alias sound-slot-1 snd-bt87x


Reiniciamos el equipo y comprobamos que los módulos cargan automáticamente.
 

¡Obsoleto


Parcheo modulo bt87x.c

Editamos el fichero bt87x.c dentro de la carpeta del modulo que hemos compilado. He preferido desactivar toda la sección de chequeo del PCI. Comentamos toda la función de "if (status & ERROR_INTERRUPTS)".

# cd alsa-driver-1.0.6a/alsa-kernel/pci/
# gedit bt87x.c

Añadimos /* al comienzo de la línea 252.
Añadimos */ al final de la línea 267.

# cd alsa-driver-1.0.6a
# make
# make install

Descargamos y cargamos el modulo:

# rmmod snd-bt87x
# modprobe snd-bt87x



Captura de prueba (2)

# arecord -D hw:1,1 -f S16_LE -t wav test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
Warning: rate is not accurate (requested = 8000Hz, got = 119466Hz)
         please, try the plug plugin (-Dplug:hw:1,1)

Ahora, lógicamente, ya no aparecen los mensajes de error en el bus PCI. Probamos con velocidades mas altas:

# arecord -D hw:1,1 -r 192000 -f S16_LE -t wav test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 192000 Hz, Mono

Funciona correctamente. Ahora la siguiente velocidad de 448000 Sps:

# arecord -D hw:1,1 -r 448000 -f S16_LE -t wav test.wav
arecord: main:434: bad speed value 448000

Falla. La utilidad ALSA esta limitada a 192000 Sps.

 

Parcheo aplay.c

Modificamos aplay.c para que nos permita velocidades superiores. Nos situamos en el directorio de las utilidades ALSA que hemos instalado anteriormente. La utilidad arecord es un alias de aplay.

# cd alsa-utils-1.0.6/aplay
# gedit aplay.c

Nos situamos en la línea 433 y modificamos el valor 192000 por 896000:

if (tmp < 2000 || tmp > 896000) {

Grabamos y compilamos nuevamente.

# cd alsa-utils-1.0.6
# make
# make install
 

¡Obsoleto


Captura de prueba (3)

# arecord -D hw:1,1 -r 448000 -f S16_LE -t wav test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 448000 Hz, Mono

Funciona correctamente. Probamos la siguiente velocidad 896000 Sps.

# arecord -D hw:1,1 -r 896000 -f S16_LE -t wav test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 896000 Hz, Mono
Warning: rate is not accurate (requested = 896000Hz, got = 448000Hz)
         please, try the plug plugin (-Dplug:hw:1,1)

Falla. Tenemos límite de 448000 en el modulo.

 

Parcheo modulo bt87x.c (2)

Modificamos otra vez el modulo bt87x.c para obtener mayor velocidad de muestreo.

# cd alsa-driver-1.0.6a/alsa-kernel/pci/
# gedit bt87x.c

Nos situamos en la línea 308 y sustituimos el valor 448000 por 896000:

.rate_max = 896000,

Nos situamos en la línea 351 y sustituimos el valor 4 por 2:

.den_min = 2,

Grabamos y compilamos nuevamente:

# make
# make install

Descargamos y cargamos el modulo:

# rmmod snd-bt87x
# modprobe snd-bt87x

Realizamos captura de prueba:

# arecord -D hw:1,1 -r 896000 -f S16_LE -t wav test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 896000 Hz, Mono

Y funciona correctamente. Ahora tenemos ALSA funcionando a 896000 Sps. Obtenemos el siguiente análisis de espectro utilizando la técnica del "cable alrededor de un aparato de televisión" (descrito en un artículo anterior).

alsa-spectrum-896000-test-signal-bt878a-adc-tv


 

¡Obsoleto

 

SoX bajo ALSA

SoX soporta ALSA pero es necesario compilarlo para poder acceder a un periférico nativo (?). Descargo la última versión estable (sox-12.17.5.tar.gz) de aquí http://sox.sourceforge.net/.

Compilamos:

# cd sox-12.17.5
# ./configure

Aparece este Warning pero lo ignoramos:

...
configure: WARNING: sound/asound.h: present but cannot be compiled
configure: WARNING: sound/asound.h: check for missing prerequisite headers?
configure: WARNING: sound/asound.h: proceeding with the preprocessor's result
configure: WARNING:     ## ------------------------------------ ##
configure: WARNING:     ## Report this to bug-autoconf@gnu.org. ##
configure: WARNING:     ## ------------------------------------ ##
...


# make

Aparece el siguiente error:

cc -g -O2 -Wall -I. -I.   -c -o alsa.o alsa.c
In file included from alsa.c:32:
/usr/include/sound/asound.h:140: error: syntax error before '*' token
/usr/include/sound/asound.h:143: error: syntax error before '}' token
/usr/include/sound/asound.h:149: error: invalid application of `sizeof' to an incomplete type
/usr/include/sound/asound.h:451: error: variable or field `__user' declared void
/usr/include/sound/asound.h:451: error: syntax error before '*' token
/usr/include/sound/asound.h:453: error: syntax error before '}' token
/usr/include/sound/asound.h:457: error: variable or field `__user' declared void
/usr/include/sound/asound.h:457: error: syntax error before '*' token
/usr/include/sound/asound.h:459: error: syntax error before '}' token
/usr/include/sound/asound.h:484: error: invalid application of `sizeof' to an incomplete type
/usr/include/sound/asound.h:485: error: invalid application of `sizeof' to an incomplete type
/usr/include/sound/asound.h:486: error: invalid application of `sizeof' to an incomplete type
/usr/include/sound/asound.h:487: error: invalid application of `sizeof' to an incomplete type
/usr/include/sound/asound.h:781: error: syntax error before '*' token
/usr/include/sound/asound.h:783: error: syntax error before '}' token
/usr/include/sound/asound.h:845: error: invalid application of `sizeof' to an incomplete type
make: *** [alsa.o] Error 1

En este articulo: http://lwn.net/Articles/28348/ se encuentra el header que falta. Editamos el fichero /usr/include/sound/asound.h

# gedit /usr/include/sound/asound.h

En la línea 22 (por ejemplo) añadimos el texto:

#define __user __attribute__((address_space(1)))

Compilamos nuevamente e instalamos:

# make
# make install

Comprobamos la instalación de SoX y observamos que ALSA es uno de los "tipos" soportados:

# sox -h
sox: Version 12.17.5
Usage: [ gopts ] [ fopts ] ifile [ fopts ] ofile [ effect [ effopts ] ]
gopts: -e -h -p -v volume -V
fopts: -r rate -c channels -s/-u/-U/-A/-a/-i/-g/-f -b/-w/-l/-d -x
effect: avg band bandpass bandreject chorus compand copy dcshift deemph earwax echo echos fade filter flanger highp highpass lowp lowpass map mask pan phaser pick pitch polyphase rate repeat resample reverb reverse silence speed stat stretch swap synth trim vibro vol
effopts: depends on effect
Supported file formats: aiff al alsa au auto avr cdr cvs dat vms gsm hcom la lu maud nul ossdsp prc raw sb sf sl smp sndt sph 8svx sw txw ub ul uw voc vorbis vox wav wve

El problema que aparece ahora es que SoX genera error "ioctl opeation failed 22" con todas las combinaciones de parámetros.

# sox -V -r 448000 -sw -t alsa /dev/snd/pcmC1D1c -t .wav test.wav
sox: Failed reading /dev/snd/pcmC1D1c: ioctl operation failed 22

-V   Verbose
-r   Sample rate
-sw  Signed Word (?)
-b   Byte (probado pero da el mismo error)
-w   Word (16 bits) (probado pero da el mismo error)
/dev/snd/pcmC1D1c
   Periférico nativo ALSA para el Bt878a. C1 es el segundo periférico físico (el primero es C0, mi SoundBlaster). D1 es el segundo periférico lógico (el primero es D0, la interfase digital del Bt878). Y la letra c en el nombre del periférico significa modo captura (para el modo de reproducción es p).

He comprobado el correcto funcionamiento de SoX contra ALSA al conectar a la SoundBlaster (/dev/snd/pcmC0D0c) pero no contra nuestro chip.


email sent to [SoX-Users]

Here you have more tests:

SoX with ALSA and my old “Creative ViBRA16C pnp”. Works perfect.

[root@lab root]# sox -V -w -c 1 -r 44100 -t alsa /dev/snd/pcmC0D0c -t .wav test.wav
sox: Input file /dev/snd/pcmC0D0c: using sample rate 44100
size shorts, encoding signed (2's complement), 1 channel
sox: Input file /dev/snd/pcmC0D0c: comment "/dev/snd/pcmC0D0c"

sox: Writing Wave file: Microsoft PCM format, 1 channel, 44100 samp/sec
sox: 88200 byte/sec, 2 block align, 16 bits/samp
sox: Output file test.wav: using sample rate 44100
size shorts, encoding signed (2's complement), 1 channel
sox: Output file: comment "/dev/snd/pcmC0D0c"

sox: Finished writing Wave file, 196608 data bytes 98304 samples


But there is no way to make the Bt878a to work.

[root@lab root]# sox -V -b -c 1 -r 448000 -t alsa /dev/snd/pcmC1D1c -t .wav test.wav
sox: Failed reading /dev/snd/pcmC1D1c: ioctl operation failed 22

[root@lab root]# sox -V -w -c 1 –r 448000 -t alsa /dev/snd/pcmC1D1c -t .wav test.wav
sox: Failed reading /dev/snd/pcmC1D1c: ioctl operation failed 22

[root@lab root]# sox -V -w -c 2 –r 448000 -t alsa /dev/snd/pcmC1D1c -t .wav test.wav
sox: Failed reading /dev/snd/pcmC1D1c: ioctl operation failed 22

And default sample rate:

[root@lab root]# sox -V -w -c 1 -t alsa /dev/snd/pcmC1D1c -t .wav test.wav
sox: Failed reading /dev/snd/pcmC1D1c: ioctl operation failed 22


The conclusion is clear: I have some problem with the Bt878 driver. It’s strange because with the native arecord utility works well.

I’ll try to activate some kind of debug into the driver.

I’ll keep you posted.

Bye.


 

¡Obsoleto

 

 

 

ToDo List

- Conseguir que SoX funcione con ALSA
- Comprobar el correcto funcionamiento del emulador OSS de ALSA con Audacity y baudline
-

 

- Agradecimientos

Clemens Ladisch



- Autor:

Juan Domenech Fernandez
jdf at tinet dot org
http://www.domenech.org
Se agradecerán cualquier tipo de comentarios por email con el Subject: [domenech]

English Version

v0.2 16-octubre-2004
v0 11-octubre-2004

 

 

¡Obsoleto