Subject: kern/1072: setting the output sampling rate of a sound blaster.
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: Roland C Dowdeswell <roland@dowdeswell-rola.eigenmann.indiana.edu>
List: netbsd-bugs
Date: 05/20/1995 01:20:04
>Number:         1072
>Category:       kern
>Synopsis:       setting the output sampling rate of a sound blaster.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 20 01:20:02 1995
>Originator:     Roland C Dowdeswell
>Organization:
"	"
>Release:        1.0
>Environment:
	
System: NetBSD arioch 1.0A NetBSD 1.0A (ARIOCH) #0: Wed May 17 17:17:56 EST 1995 root@arioch:/usr/src/sys/arch/i386/compile/ARIOCH i386


>Description:
The soundblaster driver has a hard time changing the output sample rates.
This stumped me a bit at first, because the code certainly looked like it
was changing the rates in the same way as the code in NetBSD 1.0, so I
added a few printf's and discovered that the out sample rate was being
changed, and then immediately after it was changed back to 8000.  Some more
exploration showed that if I changed both the play and record sampling
rates the problem went away.

>How-To-Repeat:

                      AUDIO_INITINFO(&the_info);
                      the_info.play.sample_rate = ret;
                      ret = ioctl(audio, AUDIO_SETINFO, &the_info);


>Fix:
For a work around, one could always set record and play at the same time.
(a bit of a hack.)

As for the kernel, I found:
int
sbdsp_commit_settings(addr)
        void *addr;
{
        /* due to potentially unfortunate ordering in the above layers,
           re-do a few sets which may be important--input gains
           (adjust the proper channels), number of input channels (hit the
           record rate and set mode) */

        register struct sbdsp_softc *sc = addr;

        sbdsp_set_out_sr_real(addr, sc->sc_orate);
        sbdsp_set_in_sr_real(addr, sc->sc_irate);

        sc->sc_last_hsw_size = sc->sc_last_hsr_size = 0;
        return(0);
}

sbdsp_set_{in|out}_sr_real() actually adjust the sampling rate, so since
sbdsp_set_in_sr_real() is called last, you always get the out sample
rate.  To fix it, I think that one would have to add a variable to
struct sbdsp_softc to indicate the current mode (record or play),
and change sbdsp_set_{in|out}_sr_real() so that only the right one
changes the actual sampling rate.
>Audit-Trail:
>Unformatted: