From alsa-devel-owner@alsa.jcu.cz  Fri Apr 17 22:28:52 1998
Received: from sandy.force9.co.uk (chrisb@25.usr02.wor.dialup.force9.net [195.166.131.89] (may be forged))
	by marvin.jcu.cz (8.8.8/8.8.8) with ESMTP id WAA26626
	for <alsa-devel@alsa.jcu.cz>; Fri, 17 Apr 1998 22:28:23 +0200
Received: (from chrisb@localhost)
	by sandy.force9.co.uk (8.8.5/8.8.5) id VAA05442
	for alsa-devel@alsa.jcu.cz; Fri, 17 Apr 1998 21:28:40 GMT
From: Christopher Butler <chrisb@sandy.force9.co.uk>
Message-Id: <199804172128.VAA05442@sandy.force9.co.uk>
Subject: Bugfixes in lowlevel sb8 code.
To: alsa-devel@alsa.jcu.cz
Date: Fri, 17 Apr 1998 21:28:28 +0000 (UTC)
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

Hi!

Here's a relativly small patch that makes a lot of difference :)

The rate computing in the SB Pro code was incorrect: the calculation
was incorrect, meaning that sound came out at half the rate it
should. Also, a break in the wrong place meant pchn->real_rate wasn't
updated.

In addition, in kernel/pcm.c, snd_pcm_format calls
pchn->hw.compute_rate *before* setting pchn->voices, therefore, when
snd_sb8_compute_rate checked for stereo, it was incorrect.

If anyone's interested, I've also written preliminary ALSA drivers for
timidity and mikmod.

--
Chris Butler <chrisb@sandy.force9.co.uk>

*** begin /tmp/alsa-sb8.patch ***
diff -urN alsadriver-0.0.11.orig/CHANGELOG alsadriver-0.0.11/CHANGELOG
--- alsadriver-0.0.11.orig/CHANGELOG	Fri Apr 17 20:04:07 1998
+++ alsadriver-0.0.11/CHANGELOG	Fri Apr 17 20:12:54 1998
@@ -2,9 +2,11 @@
 
 * native PCM
   - fixed time computing for playback
+  - set number of voices before computing rate, instead of afterwards
 * PCM OSS emulation
   - quake works now ok again - fixed error from 0.0.11
   - fixed error with large buffers - (affected Doom etc...)
+* stereo rate calculation fixed for SB Pro
 
 0.0.10 -> 0.0.11
 
diff -urN alsadriver-0.0.11.orig/kernel/pcm.c alsadriver-0.0.11/kernel/pcm.c
--- alsadriver-0.0.11.orig/kernel/pcm.c	Fri Apr 17 20:04:07 1998
+++ alsadriver-0.0.11/kernel/pcm.c	Fri Apr 17 20:08:58 1998
@@ -984,8 +984,8 @@
       err = -EINVAL;
   }
   pchn -> rate = format.rate;
-  pchn -> hw.compute_rate( pcm );
   pchn -> voices = format.channels;
+  pchn -> hw.compute_rate( pcm );
   pchn -> flags |= SND_PCM_FLG_BUFFERS;
   pchn -> neutral_byte = pchn -> mode & SND_PCM_MODE_16 ? 0x00 : 0x80;
   return err;
diff -urN alsadriver-0.0.11.orig/kernel/pcm_oss.c alsadriver-0.0.11/kernel/pcm_oss.c
--- alsadriver-0.0.11.orig/kernel/pcm_oss.c	Fri Apr 17 20:04:07 1998
+++ alsadriver-0.0.11/kernel/pcm_oss.c	Fri Apr 17 16:14:46 1998
@@ -1524,7 +1524,7 @@
     snd_pcm_oss_compute_blocks( pcm, SND_PCM_PLAYBACK );
   
   if ( fflags & SND_PCM_LFLG_RECORD ) {
-    snd_pcm_oss_trigger_record( pcm, pchn );
+    snd_pcm_oss_trigger_record( pcm, record );
     snd_spin_lock( pcm, record_sleep, &flags );
     record -> flags |= SND_PCM_FLG_SLEEP;
     snd_poll_wait( file, pcm, record, wait );
diff -urN alsadriver-0.0.11.orig/lowlevel/sb/sb8.c alsadriver-0.0.11/lowlevel/sb/sb8.c
--- alsadriver-0.0.11.orig/lowlevel/sb/sb8.c	Fri Apr 10 13:38:07 1998
+++ alsadriver-0.0.11/lowlevel/sb/sb8.c	Fri Apr 17 19:45:53 1998
@@ -69,15 +69,19 @@
       if ( direction == SND_PCM_RECORD ) {
         if ( rate > 15000 ) rate = 15000;
       }
-      if ( pchn -> voices > 2 ) {
-        rate = rate > (22050 + 11025) / 2 ? 22050 : 11025;
-        codec -> speed8 = (65536 - (256000000 + rate / 2) / rate) >> 8;
+      if ( pchn -> voices > 1 ) {
+/* This doesn't look right to me - Chris Butler */
+/*         rate = rate > (22050 + 11025) / 2 ? 22050 : 11025; */
+	if (rate < 4000) rate = 4000;
+	if (rate > 22050) rate = 22050;
+        codec -> speed8 = (65536 - (256000000 + rate) / (rate * 2)) >> 8;
         if ( direction == SND_PCM_PLAYBACK ) {
           codec -> fmt8 = SB_DSP_HI_OUTPUT_AUTO;
         } else {
           codec -> fmt8 = SB_DSP_HI_INPUT_AUTO;
         }
-        break;
       } else {
         if ( rate < 4000 ) rate = 4000;
         if ( rate > 44100 ) rate = 44100;
@@ -89,6 +93,8 @@
         }
       }
       pchn -> real_rate = 256000000 / (65536 - (codec -> speed8 << 8));
+      snd_printd( "snd_sb8_compute_rate: rate = %u, pchn->real_rate = %u\n",
+		  rate, pchn->real_rate);
       break;
     default:
       snd_printd( "unknown hardware for sb8 compute rate!!!\n" );


