Date: Wed, 09 Nov 2005 00:36:20 +0900 From: Watanabe Kazuhiro <CQG00620@nifty.ne.jp> To: freebsd-multimedia <freebsd-multimedia@freebsd.org> Subject: [patch] stereo input is mixed to monaural via SoundBlaster16 recording mixer Message-ID: <20051108153556.C856C253D6@mail.asahi-net.or.jp>
next in thread | raw e-mail | index | archive | help
Hi, all. I have a SoundBlaster Vibra16S(CT2800) soundcard. When I try to record with wavrec (a part of ports/audio/wavplay), even if an input source is 2-channel stereo, the recording output becomes 2-channel monaural. * Environment (FreeBSD-current; CVSup'ed Nov. 8) $ uname -a FreeBSD scorpio.zodiac.org 7.0-CURRENT FreeBSD 7.0-CURRENT #4: Tue Nov 8 18:41:14 JST 2005 nabe@scorpio.zodiac.org:/FreeBSD/obj-current/FreeBSD/FreeBSD-current/src/sys/GENERIC i386 $ cat /dev/sndstat FreeBSD Audio Driver (newpcm) Installed devices: pcm0: <Avance Logic ALS4000> at io 0xe800 irq 9 kld snd_als4000 (1p/1r/0v channels duplex default) pcm1: <SB16 DSP 4.13> at io 0x240 irq 5 drq 1:5 bufsz 4096 kld snd_sb16 (1p/1r/0v channels duplex) pcm2: <CS423x> at io 0x534 irq 10 drq 3:0 bufsz 4096 (1p/1r/0v channels duplex) * How to test $ mixer -f /dev/mixer1 =rec cd Recording source: cd $ cdcontrol play && wavrec -d /dev/dsp1 -M -s 44100 -b 16 -t 30 mono.wav $ cdcontrol stop $ cdcontrol play && wavrec -d /dev/dsp1 -S -s 44100 -b 16 -t 30 stereo.wav $ cdcontrol stop $ wavplay -d /dev/dsp1 mono.wav stereo.wav Pathname: mono.wav Device: /dev/dsp1 Sampling Rate: 44100 Hz Mode: Mono Samples: 1323000 Bits: 16 Pathname: stereo.wav Device: /dev/dsp1 Sampling Rate: 44100 Hz Mode: Stereo Samples: 1323000 Bits: 16 /* listen the two files carefully... */ This behavior is hard-coded in /sys/dev/sound/isa/sb16.c: | static int | sb16mix_setrecsrc(struct snd_mixer *m, u_int32_t src) | { | struct sb_info *sb = mix_getdevinfo(m); | u_char recdev; | | recdev = 0; | if (src & SOUND_MASK_MIC) | recdev |= 0x01; /* mono mic */ | | if (src & SOUND_MASK_CD) | recdev |= 0x06; /* l+r cd */ | | if (src & SOUND_MASK_LINE) | recdev |= 0x18; /* l+r line */ | | if (src & SOUND_MASK_SYNTH) | recdev |= 0x60; /* l+r midi */ | | sb_setmixer(sb, SB16_IMASK_L, recdev); | sb_setmixer(sb, SB16_IMASK_R, recdev); This behavior has not been changed since the newpcm driver was commited to the FreeBSD source tree (8 years ago). It seems that there is no one who is worried about this behavior; even so, I think these are improper settings as default. It's a fix patch. This patch also fixes `cat /dev/sndstat` output. I've referred to following sources: sb_mixer.[ch] (OSS/Free sound driver) ftp://sources.freebsd.org/pub/FreeBSD/sources/RELENG_4/src/sys/i386/isa/sound/ "Hardware Programming Reference" pp70 ("Register Map of CT1745 Mixer") http://www.alsa-project.org/alsa/ftp/datasheets/creative/hwmnl.pdf --- sys/dev/sound/isa/sb16.c.orig Mon Oct 10 00:44:31 2005 +++ sys/dev/sound/isa/sb16.c Mon Nov 7 14:33:38 2005 @@ -370,23 +370,28 @@ static int sb16mix_setrecsrc(struct snd_mixer *m, u_int32_t src) { struct sb_info *sb = mix_getdevinfo(m); - u_char recdev; + u_char recdev_l, recdev_r; - recdev = 0; + recdev_l = 0; + recdev_r = 0; if (src & SOUND_MASK_MIC) - recdev |= 0x01; /* mono mic */ + recdev_l |= 0x01; /* mono mic */ + recdev_r |= 0x01; if (src & SOUND_MASK_CD) - recdev |= 0x06; /* l+r cd */ + recdev_l |= 0x04; /* l cd */ + recdev_r |= 0x02; /* r cd */ if (src & SOUND_MASK_LINE) - recdev |= 0x18; /* l+r line */ + recdev_l |= 0x10; /* l line */ + recdev_r |= 0x08; /* r line */ if (src & SOUND_MASK_SYNTH) - recdev |= 0x60; /* l+r midi */ + recdev_l |= 0x40; /* l midi */ + recdev_r |= 0x20; /* r midi */ - sb_setmixer(sb, SB16_IMASK_L, recdev); - sb_setmixer(sb, SB16_IMASK_R, recdev); + sb_setmixer(sb, SB16_IMASK_L, recdev_l); + sb_setmixer(sb, SB16_IMASK_R, recdev_r); /* Switch on/off FM tuner source */ if (src & SOUND_MASK_LINE1) @@ -849,7 +854,7 @@ sb16_attach(device_t dev) else status2[0] = '\0'; - snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld%s bufsz %ud %s", + snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld drq %ld%s bufsz %u %s", rman_get_start(sb->io_base), rman_get_start(sb->irq), rman_get_start(sb->drq1), status2, sb->bufsize, PCM_KLDSTRING(snd_sb16)); --- Watanabe Kazuhiro (CQG00620@nifty.ne.jp)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051108153556.C856C253D6>