From nobody@FreeBSD.org  Wed Jan 11 20:51:08 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id CE00716A41F
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Jan 2006 20:51:08 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 8235E43D46
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Jan 2006 20:51:08 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k0BKp8tp053338
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 11 Jan 2006 20:51:08 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k0BKp88l053337;
	Wed, 11 Jan 2006 20:51:08 GMT
	(envelope-from nobody)
Message-Id: <200601112051.k0BKp88l053337@www.freebsd.org>
Date: Wed, 11 Jan 2006 20:51:08 GMT
From: Marc Flambard <marc-pub@sarambard.homedns.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: "bug" on sound driver & solution
X-Send-Pr-Version: www-2.3

>Number:         91683
>Category:       kern
>Synopsis:       [sound] [patch] bug on sound driver & solution
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ariff
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 11 21:00:19 GMT 2006
>Closed-Date:    Sun Jan 29 04:03:05 GMT 2006
>Last-Modified:  Sun Jan 29 04:03:05 GMT 2006
>Originator:     Marc Flambard
>Release:        6.0
>Organization:
RAC Technologie
>Environment:
FreeBSD pc-marc1.maison 6.0-STABLE FreeBSD 6.0-STABLE #21: Tue Jan 10 17:10:37 CET 2006     marc@pc-marc1.maison:/usr/obj/usr/src/sys/pc-marc-v3  i386
>Description:
I found "bug" on sound driver (channel.c,v 1.99.2.1 & feeder.c,v 1.33.2.1).
I use CS4630 based sound card (minimum 11025Hz at recording).

Changing format capacity for record channel on csa driver(csapcm.c),
reveals some interesting things.
I show you sndstat on 2 situations (I use application that require 8Khz mono)

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_S16_LE,
	AFMT_STEREO | AFMT_S16_LE,
	0
};
SNDSTAT:
{hardware} -> feeder_root(0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}

here everything is ok.

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_STEREO | AFMT_S16_LE,
	AFMT_S16_LE,
	0
};
SNDSTAT:
{hardware} -> feeder_root(0x00000010) -> feeder_monotostereo16(0x00000010 -> 0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}

why using mono capacity with feeder_monotostereo whereas the hardware is able to deliver stereo?

>How-To-Repeat:
change record format order of your sound card
example for csa:
static u_int32_t csa_recfmt[] = {
	AFMT_S16_LE,
	AFMT_STEREO | AFMT_S16_LE,
	0
};
change by:
static u_int32_t csa_recfmt[] = {
	AFMT_STEREO | AFMT_S16_LE,
	AFMT_S16_LE,
	0
};

>Fix:
In function feeder_fmtchain(feeder.c):
if we test maxdepth before testing validity,
the function chn_fmtchain(feeder.c) will be able to
distinguish the difference between [feeder_root->feeder_monotostereo16->feeder_rate]
and [feeder_root->feeder_rate] without dependency on format arrangement and
without changes made between feeder.c-v1.33 and v1.33.2.1 (particularly reverse scanning!).
Moreover this change simplify chn_buildfeeder(channel.c).

I join diffs and tests with debug messages.

Marc Flambard

Tests with debug messages:

-----ACTUALLY-----

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_S16_LE,
	AFMT_STEREO | AFMT_S16_LE,
	0
};
SNDSTAT:
{hardware} -> feeder_root(0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}
DEBUG:
Jan 11 15:55:46 pc-marc1 kernel: setspeed, channel pcm0:record:0
Jan 11 15:55:46 pc-marc1 kernel: want speed 8000, try speed 11025, got speed 11025
Jan 11 15:55:46 pc-marc1 kernel: feederflags 10
Jan 11 15:55:46 pc-marc1 kernel: find feeder type 4, got 0xc76efce0
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>type:4
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>c->format:00000010
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>fc->desc->in:10000010
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>fc->desc->out:10000010
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>c->feeder->desc->out:00000010
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>fmtlist[0]:00000010
Jan 11 15:55:46 pc-marc1 kernel: chn_buildfeeder>>fmtlist[1]:10000010
Jan 11 15:55:46 pc-marc1 kernel: build fmtchain from 0x10 to 0x10000010:
Jan 11 15:55:46 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:55:46 pc-marc1 kernel: got it
Jan 11 15:55:46 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_endian16 (10 -> 20)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_sign16le (10 -> 80)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_monotostereo16 (10 -> 10000010)...
Jan 11 15:55:46 pc-marc1 kernel: got it
Jan 11 15:55:46 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:55:46 pc-marc1 kernel: got it
Jan 11 15:55:46 pc-marc1 kernel: ok
Jan 11 15:55:46 pc-marc1 kernel: added feeder 0xc76efce0, output 0x10000010
Jan 11 15:55:46 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:55:46 pc-marc1 kernel: got it
Jan 11 15:55:46 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:55:46 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:55:46 pc-marc1 kernel: got it
Jan 11 15:55:46 pc-marc1 kernel: r = 0
Jan 11 15:55:46 pc-marc1 kernel: chn_setblocksize(0, 0)
Jan 11 15:55:46 pc-marc1 kernel: feedrate = 0xc5e26180
Jan 11 15:55:46 pc-marc1 kernel: feeder_set(FEEDRATE_SRC, 11025) = 0
Jan 11 15:55:46 pc-marc1 kernel: feeder_set(FEEDRATE_DST, 8000) = 0
Jan 11 15:55:46 pc-marc1 kernel: setspeed done, r = 0

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_STEREO | AFMT_S16_LE,
	AFMT_S16_LE,
	0
};
SNDSTAT:
{hardware} -> feeder_root(0x00000010) -> feeder_monotostereo16(0x00000010 -> 0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}
DEBUG:
Jan 11 15:59:21 pc-marc1 kernel: setspeed, channel pcm0:record:0
Jan 11 15:59:21 pc-marc1 kernel: want speed 8000, try speed 11025, got speed 11025
Jan 11 15:59:21 pc-marc1 kernel: feederflags 10
Jan 11 15:59:21 pc-marc1 kernel: find feeder type 4, got 0xc76efce0
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>type:4
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>c->format:00000010
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>fc->desc->in:10000010
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>fc->desc->out:10000010
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>c->feeder->desc->out:00000010
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>fmtlist[0]:10000010
Jan 11 15:59:21 pc-marc1 kernel: chn_buildfeeder>>fmtlist[1]:00000010
Jan 11 15:59:21 pc-marc1 kernel: build fmtchain from 0x10 to 0x10000010:
Jan 11 15:59:21 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_endian16 (10 -> 20)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_sign16le (10 -> 80)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_monotostereo16 (10 -> 10000010)...
Jan 11 15:59:21 pc-marc1 kernel: got it
Jan 11 15:59:21 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:59:21 pc-marc1 kernel: got it
Jan 11 15:59:21 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_endian16 (10 -> 20)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_sign16le (10 -> 80)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_monotostereo16 (10 -> 10000010)...
Jan 11 15:59:21 pc-marc1 kernel: got it
Jan 11 15:59:21 pc-marc1 kernel: ok
Jan 11 15:59:21 pc-marc1 kernel: added feeder 0xc76efce0, output 0x10000010
Jan 11 15:59:21 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:59:21 pc-marc1 kernel: got it
Jan 11 15:59:21 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:59:21 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:59:21 pc-marc1 kernel: got it
Jan 11 15:59:21 pc-marc1 kernel: r = 0
Jan 11 15:59:21 pc-marc1 kernel: chn_setblocksize(0, 0)
Jan 11 15:59:21 pc-marc1 kernel: feedrate = 0xc5e1eac0
Jan 11 15:59:21 pc-marc1 kernel: feeder_set(FEEDRATE_SRC, 11025) = 0
Jan 11 15:59:21 pc-marc1 kernel: feeder_set(FEEDRATE_DST, 8000) = 0
Jan 11 15:59:21 pc-marc1 kernel: setspeed done, r = 0

-----WITH MY MODIFICATIONS-----

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_S16_LE,
	AFMT_STEREO | AFMT_S16_LE,
SNDSTAT:
{hardware} -> feeder_root(0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}
DEBUG:
Jan 11 15:29:17 pc-marc1 kernel: setspeed, channel pcm0:record:0
Jan 11 15:29:17 pc-marc1 kernel: want speed 8000, try speed 11025, got speed 11025
Jan 11 15:29:17 pc-marc1 kernel: feederflags 10
Jan 11 15:29:17 pc-marc1 kernel: find feeder type 4, got 0xc752ac40
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>type:4
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>c->format:00000010
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>fc->desc->in:10000010
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>fc->desc->out:10000010
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>c->feeder->desc->out:00000010
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>fmtlist[0]:00000010
Jan 11 15:29:17 pc-marc1 kernel: chn_buildfeeder>>fmtlist[1]:10000010
Jan 11 15:29:17 pc-marc1 kernel: build fmtchain from 0x10 to 0x10000010:
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain with maxdepth=1
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_endian16 (10 -> 20)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_sign16le (10 -> 80)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_monotostereo16 (10 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: got it
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: got it
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: got it
Jan 11 15:29:17 pc-marc1 kernel: ok
Jan 11 15:29:17 pc-marc1 kernel: added feeder 0xc752ac40, output 0x10000010
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain with maxdepth=1
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:29:17 pc-marc1 kernel: got it
Jan 11 15:29:17 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=1)
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:29:17 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:29:17 pc-marc1 kernel: got it
Jan 11 15:29:17 pc-marc1 kernel: r = 0
Jan 11 15:29:17 pc-marc1 kernel: chn_setblocksize(0, 0)
Jan 11 15:29:17 pc-marc1 kernel: feedrate = 0xc5669000
Jan 11 15:29:17 pc-marc1 kernel: feeder_set(FEEDRATE_SRC, 11025) = 0
Jan 11 15:29:17 pc-marc1 kernel: feeder_set(FEEDRATE_DST, 8000) = 0
Jan 11 15:29:17 pc-marc1 kernel: setspeed done, r = 0

WITH:
static u_int32_t csa_recfmt[] = {
	AFMT_STEREO | AFMT_S16_LE,
	AFMT_S16_LE,
	0
};
SNDSTAT:
{hardware} -> feeder_root(0x10000010) -> feeder_rate(11025 -> 8000) -> feeder_stereotomono16(0x10000010 -> 0x00000010) -> {userland}
DEBUG:
Jan 11 15:39:02 pc-marc1 kernel: setspeed, channel pcm0:record:0
Jan 11 15:39:02 pc-marc1 kernel: want speed 8000, try speed 11025, got speed 11025
Jan 11 15:39:02 pc-marc1 kernel: feederflags 10
Jan 11 15:39:02 pc-marc1 kernel: find feeder type 4, got 0xc76efc40
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>type:4
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>c->format:00000010
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>fc->desc->in:10000010
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>fc->desc->out:10000010
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>c->feeder->desc->out:00000010
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>fmtlist[0]:10000010
Jan 11 15:39:02 pc-marc1 kernel: chn_buildfeeder>>fmtlist[1]:00000010
Jan 11 15:39:02 pc-marc1 kernel: build fmtchain from 0x10 to 0x10000010:
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: got it
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain with maxdepth=1
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_root (0 -> 10)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_endian16 (10 -> 20)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_sign16le (10 -> 80)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_monotostereo16 (10 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: got it
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=0)
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_root (0 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: got it
Jan 11 15:39:02 pc-marc1 kernel: ok
Jan 11 15:39:02 pc-marc1 kernel: added feeder 0xc76efc40, output 0x10000010
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain with maxdepth=0
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain with maxdepth=1
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:39:02 pc-marc1 kernel: got it
Jan 11 15:39:02 pc-marc1 kernel: call feeder_fmtchain for best chain (maxdepth=1)
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_rate (10000010 -> 10000010)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_endian16 (10000010 -> 10000020)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_sign16le (10000010 -> 10000080)...
Jan 11 15:39:02 pc-marc1 kernel: trying feeder_stereotomono16 (10000010 -> 10)...
Jan 11 15:39:02 pc-marc1 kernel: got it
Jan 11 15:39:02 pc-marc1 kernel: r = 0
Jan 11 15:39:02 pc-marc1 kernel: chn_setblocksize(0, 0)
Jan 11 15:39:02 pc-marc1 kernel: feedrate = 0xc57ff8c0
Jan 11 15:39:02 pc-marc1 kernel: feeder_set(FEEDRATE_SRC, 11025) = 0
Jan 11 15:39:02 pc-marc1 kernel: feeder_set(FEEDRATE_DST, 8000) = 0
Jan 11 15:39:02 pc-marc1 kernel: setspeed done, r = 0


diffs:

-----channel.diff-----
1292c1292
< 	int err;
---
> 	int err,cnt;
1361,1372c1361,1375
< 			if ((type == FEEDER_RATE &&
< 					!fmtvalid(fc->desc->in, fmtlist))
< 					|| c->feeder->desc->out != fc->desc->in) {
<  				DEB(printf("build fmtchain from 0x%x to 0x%x: ", c->feeder->desc->out, fc->desc->in));
< 				tmp[0] = fc->desc->in;
< 				tmp[1] = 0;
< 				if (chn_fmtchain(c, tmp) == 0) {
< 					DEB(printf("failed\n"));
< 
< 					return ENODEV;
< 				}
<  				DEB(printf("ok\n"));
---
>  			DEB(printf("chn_buildfeeder>>c->format:%08x\n", c->format));
>  			DEB(printf("chn_buildfeeder>>fc->desc->in:%08x\n", fc->desc->in));
>  			DEB(printf("chn_buildfeeder>>fc->desc->out:%08x\n", fc->desc->out));
>  			DEB(printf("chn_buildfeeder>>c->feeder->desc->out:%08x\n", c->feeder->desc->out));
> 			cnt=-1;
> 			while(fmtlist[++cnt])
>  			   DEB(printf("chn_buildfeeder>>fmtlist[%i]:%08x\n", cnt, fmtlist[cnt]));
> 
>  			DEB(printf("build fmtchain to 0x%x:\n", fc->desc->in));
> 			tmp[0] = fc->desc->in;
> 			tmp[1] = 0;
> 			if (chn_fmtchain(c, tmp) == 0) {
> 				DEB(printf("failed\n"));
> 
> 				return ENODEV;
1373a1377
>  			DEB(printf("ok\n"));
1385,1396c1389,1394
< 	if (fmtvalid(c->feeder->desc->out, fmtlist)
< 			&& !(c->direction == PCMDIR_REC &&
< 				c->format != c->feeder->desc->out))
< 		hwfmt = c->feeder->desc->out;
< 	else {
< 		if (c->direction == PCMDIR_REC) {
< 			tmp[0] = c->format;
< 			tmp[1] = 0;
< 			hwfmt = chn_fmtchain(c, tmp);
< 		} else
< 			hwfmt = chn_fmtchain(c, fmtlist);
< 	}
---
> 	if (c->direction == PCMDIR_REC) {
> 		tmp[0] = c->format;
> 		tmp[1] = 0;
> 		hwfmt = chn_fmtchain(c, tmp);
> 	} else
> 		hwfmt = chn_fmtchain(c, fmtlist);

-----feeder.diff-----
268c268,271
< 	/* printf("trying %s (%x -> %x)...\n", source->class->name, source->desc->in, source->desc->out); */
---
> 	if (maxdepth < 0)
> 		return NULL;
> 
> 	DEB(printf("trying %s (%x -> %x)...\n", source->class->name, source->desc->in, source->desc->out)); 
270c273
< 		/* printf("got it\n"); */
---
> 		DEB(printf("got it\n")); 
274,276d276
< 	if (maxdepth < 0)
< 		return NULL;
< 
323,326c323
< 	while (from[i] != 0)
< 		i++;
< 	while (i > 0) {
< 		i--;
---
> 	while (from[i] != 0) {
330a328
> 			DEB(printf("call feeder_fmtchain with maxdepth=%i\n",max));
343a342
> 		i++;
348a348
> 	DEB(printf("call feeder_fmtchain for best chain (maxdepth=%i)\n",bestmax));
376,385c376
< 	if (c->direction == PCMDIR_REC) {
< 		try = c->feeder;
< 		while (try != NULL) {
< 			if (try->desc->type == FEEDER_ROOT)
< 				return try->desc->out;
< 			try = try->source;
< 		}
< 		return best;
< 	} else
< 		return c->feeder->desc->out;
---
> 	return (c->direction == PCMDIR_REC)? best : c->feeder->desc->out;


Marc Flambard
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-multimedia 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Jan 11 23:01:49 UTC 2006 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=91683 
Responsible-Changed-From-To: freebsd-multimedia->ariff 
Responsible-Changed-By: ariff 
Responsible-Changed-When: Sat Jan 21 07:25:33 UTC 2006 
Responsible-Changed-Why:  
I'll take this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=91683 

From: Ariff Abdullah <ariff@FreeBSD.org>
To: bug-followup@FreeBSD.org, marc-pub@sarambard.homedns.org
Cc:  
Subject: Re: kern/91683: [sound] [patch] bug on sound driver & solution
Date: Sat, 21 Jan 2006 15:46:52 +0800

 --Signature=_Sat__21_Jan_2006_15_46_52_+0800_6GPZKY/E0dGYqaAp
 Content-Type: text/plain; charset=US-ASCII
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 Can you resubmit the patch using unified diff (diff -u) ?
 
 --
 Ariff Abdullah
 FreeBSD
 
 --Signature=_Sat__21_Jan_2006_15_46_52_+0800_6GPZKY/E0dGYqaAp
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.2 (FreeBSD)
 
 iD8DBQFD0ebvlr+deMUwTNoRAqBxAKCzhAoR6+y8gIlO801xq50nKmnLYACgsuWH
 UUU6VnrlO/pLHtEj/4xU7uM=
 =lOTv
 -----END PGP SIGNATURE-----
 
 --Signature=_Sat__21_Jan_2006_15_46_52_+0800_6GPZKY/E0dGYqaAp--

From: Marc Flambard <marc@sarambard.homedns.org>
To: bug-followup@FreeBSD.org, marc-pub@sarambard.homedns.org
Cc:  
Subject: Re: kern/91683: [sound] [patch] bug on sound driver & solution
Date: Mon, 23 Jan 2006 13:53:06 +0100

 ok...
 
 -----channel.diff-----
 
 --- channel.c.old       Wed Jan 11 16:36:11 2006
 +++ channel.c   Wed Jan 11 16:32:57 2006
 @@ -1289,7 +1289,7 @@
         struct feeder_class *fc;
         struct pcm_feederdesc desc;
         u_int32_t tmp[2], type, flags, hwfmt, *fmtlist;
 -       int err;
 +       int err,cnt;
 
         CHN_LOCKASSERT(c);
         while (chn_removefeeder(c) == 0);
 @@ -1358,19 +1358,23 @@
                                 return EOPNOTSUPP;
                         }
 
 -                       if ((type == FEEDER_RATE &&
 -                                       !fmtvalid(fc->desc->in,
 fmtlist))
 -                                       || c->feeder->desc->out !=
 fc->desc->in) {
 -                               DEB(printf("build fmtchain from 0x%x to
 0x%x: ", c->feeder->desc->out, fc->desc->in));
 -                               tmp[0] = fc->desc->in;
 -                               tmp[1] = 0;
 -                               if (chn_fmtchain(c, tmp) == 0) {
 -                                       DEB(printf("failed\n"));
 -
 -                                       return ENODEV;
 -                               }
 -                               DEB(printf("ok\n"));
 +                       DEB(printf("chn_buildfeeder>>c->format:%08x\n",
 c->format));
 +                       DEB(printf("chn_buildfeeder>>fc->desc->in:%08x
 \n", fc->desc->in));
 +                       DEB(printf("chn_buildfeeder>>fc->desc->out:%08x
 \n", fc->desc->out));
 +
 DEB(printf("chn_buildfeeder>>c->feeder->desc->out:%08x\n",
 c->feeder->desc->out));
 +                       cnt=-1;
 +                       while(fmtlist[++cnt])
 +                          DEB(printf("chn_buildfeeder>>fmtlist[%i]:%08x
 \n", cnt, fmtlist[cnt]));
 +
 +                       DEB(printf("build fmtchain to 0x%x:\n",
 fc->desc->in));
 +                       tmp[0] = fc->desc->in;
 +                       tmp[1] = 0;
 +                       if (chn_fmtchain(c, tmp) == 0) {
 +                               DEB(printf("failed\n"));
 +
 +                               return ENODEV;
                         }
 +                       DEB(printf("ok\n"));
 
                         err = chn_addfeeder(c, fc, fc->desc);
                         if (err) {
 @@ -1382,18 +1386,12 @@
                 }
         }
 
 -       if (fmtvalid(c->feeder->desc->out, fmtlist)
 -                       && !(c->direction == PCMDIR_REC &&
 -                               c->format != c->feeder->desc->out))
 -               hwfmt = c->feeder->desc->out;
 -       else {
 -               if (c->direction == PCMDIR_REC) {
 -                       tmp[0] = c->format;
 -                       tmp[1] = 0;
 -                       hwfmt = chn_fmtchain(c, tmp);
 -               } else
 -                       hwfmt = chn_fmtchain(c, fmtlist);
 -       }
 +       if (c->direction == PCMDIR_REC) {
 +               tmp[0] = c->format;
 +               tmp[1] = 0;
 +               hwfmt = chn_fmtchain(c, tmp);
 +       } else
 +               hwfmt = chn_fmtchain(c, fmtlist);
 
         if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) {
                 DEB(printf("Invalid hardware format: 0x%x\n", hwfmt));
 
 -----feeder.diff-----
 
 --- feeder.c.old        Wed Jan 11 16:35:38 2006
 +++ feeder.c    Wed Jan 11 16:17:36 2006
 @@ -265,15 +265,15 @@
         struct feedertab_entry *fte;
         struct pcm_feeder *try, *ret;
 
 -       /* printf("trying %s (%x -> %x)...\n", source->class->name,
 source->desc->in, source->desc->out); */
 +       if (maxdepth < 0)
 +               return NULL;
 +
 +       DEB(printf("trying %s (%x -> %x)...\n", source->class->name,
 source->desc->in, source->desc->out));
         if (fmtvalid(source->desc->out, to)) {
 -               /* printf("got it\n"); */
 +               DEB(printf("got it\n"));
                 return source;
         }
 
 -       if (maxdepth < 0)
 -               return NULL;
 -
         SLIST_FOREACH(fte, &feedertab, link) {
                 if (fte->desc == NULL)
                         continue;
 @@ -320,14 +320,12 @@
         i = 0;
         best = 0;
         bestmax = 100;
 -       while (from[i] != 0)
 -               i++;
 -       while (i > 0) {
 -               i--;
 +       while (from[i] != 0) {
                 c->feeder->desc->out = from[i];
                 try = NULL;
                 max = 0;
                 while (try == NULL && max < 8) {
 +                       DEB(printf("call feeder_fmtchain with maxdepth=%
 i\n",max));
                         try = feeder_fmtchain(to, c->feeder, stop, max);
                         if (try == NULL)
                                 max++;
 @@ -341,11 +339,13 @@
                         try = try->source;
                         feeder_destroy(del);
                 }
 +               i++;
         }
         if (best == 0)
                 return 0;
 
         c->feeder->desc->out = best;
 +       DEB(printf("call feeder_fmtchain for best chain (maxdepth=%
 i)\n",bestmax));
         try = feeder_fmtchain(to, c->feeder, stop, bestmax);
         if (try == NULL)
                 return 0;
 @@ -373,16 +373,7 @@
         printf("%s [%d]\n", try->class->name, try->desc->idx);
  #endif
 
 -       if (c->direction == PCMDIR_REC) {
 -               try = c->feeder;
 -               while (try != NULL) {
 -                       if (try->desc->type == FEEDER_ROOT)
 -                               return try->desc->out;
 -                       try = try->source;
 -               }
 -               return best;
 -       } else
 -               return c->feeder->desc->out;
 +       return (c->direction == PCMDIR_REC)? best :
 c->feeder->desc->out;
  }
 
  void
 
 
 
 Marc Flambard
 

From: Ariff Abdullah <ariff@FreeBSD.org>
To: Marc Flambard <marc@sarambard.homedns.org>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/91683: [sound] [patch] bug on sound driver & solution
Date: Tue, 24 Jan 2006 19:02:11 +0800

 Thanks for the submission. 
 
 Although this patch (which somehow revert everything to its original
 form before the MegaMFC) works for you, it breaks heavily if it
 involves weird combination of hardware formats (AFMT_S32_LE - under
 extreme condition) or if you intend to do recording in other format
 not supported by the hardware. Few utilities (pcmplay/pcmrec) can be
 found at http://people.freebsd.org/~ariff/utils/ , which you can use
 to do regression and torture test.
 
 A better fix has been committed to -current, and will be MFCed later.
 
 http://lists.freebsd.org/pipermail/cvs-src/2006-January/058517.html
 
 I'm closing this PR.
 
 Thanks.
 
 
 --
 Ariff Abdullah
 FreeBSD
State-Changed-From-To: open->closed 
State-Changed-By: ariff 
State-Changed-When: Sun Jan 29 04:01:58 UTC 2006 
State-Changed-Why:  
Fix has been commited. Thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=91683 
>Unformatted:
