msacm: 8 -> 16 bit sample conversion

Francois Gouget fgouget at codeweavers.com
Fri Dec 13 14:27:00 CST 2002


We support sound in either 8 bit unsigned samples or 16bit signed 
samples. msacm can convert an 8bit sample to a 16bit sample in case the 
sound card does not support 8bit sound (e.g. our friends, the i810 sound 
cards).

The current code does it this way:

     return (short)(b ^ 0x80) * 256

The problem is that this converts 255 to 32512, not 32767. If we do a 
linear conversion we get the following formula:

     s16 = (65535/255) * u8 - 32768

The above formula will nicely convert 255 to 32767 and 0 to -32768. And 
what's even nicer is that you can rewrite it as follows:

     return (short)((b+(b << 8))-32768);

I hoped to hear an improvement but there was no difference (the 
distortion was caused by the resampling instead, see next patch). 
However I think this formula is saner and it appears to be used by other 
sound processing tools so I propose to make the switch.

Changelog:

    Francois Gouget <fgouget at codeweavers.com>

  * dlls/msacm/pcmconverter.c

    Use slighly more accurate formula for C816
    Wrap a couple of comments to 80 columns

-- 
Francois Gouget
fgouget at codeweavers.com

-------------- next part --------------
Index: dlls/msacm/pcmconverter.c
===================================================================
RCS file: /home/wine/wine/dlls/msacm/pcmconverter.c,v
retrieving revision 1.14
diff -u -r1.14 pcmconverter.c
--- dlls/msacm/pcmconverter.c	13 Dec 2002 02:18:20 -0000	1.14
+++ dlls/msacm/pcmconverter.c	13 Dec 2002 19:18:51 -0000
@@ -123,15 +123,15 @@
  * parameters:
  *	+ 8 bit unsigned vs 16 bit signed
  *	+ mono vs stereo (1 or 2 channels)
- *	+ sampling rate (8.0, 11.025, 22.05, 44.1 kHz are defined, but algo shall work
- *	  in all cases)
+ *	+ sampling rate (8.0, 11.025, 22.05, 44.1 kHz are defined, but algo
+ *	  shall work in all cases)
  *
  * mono => stereo: copy the same sample on Left & Right channels
  * stereo =) mono: use the average value of samples from Left & Right channels
- * resampling; we lookup for each destination sample the two source adjacent samples
- * 	were src <= dst < src+1 (dst is increased by a fractional value which is
- *	equivalent to the increment by one on src); then we use a linear
- *	interpolation between src and src+1
+ * resampling; we lookup for each destination sample the two source adjacent
+ *      samples were src <= dst < src+1 (dst is increased by a fractional
+ *      value which is equivalent to the increment by one on src); then we
+ *      use a linear interpolation between src and src+1
  */
 
 /***********************************************************************
@@ -146,7 +154,7 @@
  */
 static inline short C816(unsigned char b)
 {
-    return (short)(b ^ 0x80) * 256;
+    return (short)((b+(b << 8))-32768);
 }
 
 /***********************************************************************
@@ -784,8 +792,8 @@
 	afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
 	afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
 	afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
-	/* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
-	 * afd->pwfx->cbSize = 0;
+	/* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not
+	 * accessible afd->pwfx->cbSize = 0;
 	 */
 	afd->pwfx->nBlockAlign =
 	    (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;


More information about the wine-patches mailing list