From alsa-devel-owner@alsa.jcu.cz  Mon Feb 15 00:39:14 1999
Received: from havoc.gtf.org (IDENT:data@panic.ohr.gatech.edu [130.207.47.194])
	by marvin.jcu.cz (8.9.1a/8.9.1) with ESMTP id AAA30553
	for <alsa-devel@alsa.jcu.cz>; Mon, 15 Feb 1999 00:39:02 +0100
Received: (from data@localhost)
	by havoc.gtf.org (8.8.7/8.8.7) id SAA09588
	for alsa-devel@alsa.jcu.cz; Sun, 14 Feb 1999 18:39:00 -0500
From: Data <data@havoc.gtf.org>
Message-Id: <199902142339.SAA09588@havoc.gtf.org>
Subject: Re: Mixing
To: alsa-devel@alsa.jcu.cz
Date: Sun, 14 Feb 1999 18:38:59 -0500 (EST)
In-Reply-To: <Pine.LNX.4.05.9902140125140.3906-100000@screech.cs.alfred.edu> from "Christopher T. Lansdown" at Feb 14, 99 01:27:36 am
Content-Type: text
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

> 
> Hello,
> 	I'm in the process of writing a music library, targeted at games.
> On of it's functions will be mixing different sounds (PCM streams).  What
> is the right way to mix PCM streams?  Adding the samples, averaging them,
> or something else?  Assume identicle sample rate and stereo.

For the highest quality you should attenuate them then add them.  Mixing in 
the analog domain is simple addition, and that's what you should do digitally.
Generally analog mixers attenuate (== reduce the volume of) the signal before 
combining, since it often happens that simple addition will drive the 
amplitude out of range.
  A quick way to do this for games & such is by bit-shifting & then adding.  
For example -

short mixemquick(short sample1, short sample2)
{
    return (sample1>>1 + sample2>>1);
}

This attenuates each sample by 6 dB.  For more attenuation, shift over more. 
Alternatively you can ensure that the soundclips & such you're using are 
_already_ attenuated so you can add them without fear.  Of course active 
envelope control is another topic entirely .. bear in mind also that you 
may not need to do this at all; it's probably worthwhile to try simple 
addition first - if it sounds OK, keep it.  There are ways to achieve 
finer control, of course, but I won't bore you with those unless you ask :)
  If you decide to enforce clipping you'll need to manipulate your samples as 
longs; otherwise you won't be able to tell when they go out of range.  If you 
do it in assembly, on the other hand, you can do it 16-bit & check the 
overflow flag.  (not real real portable unfortunately.)
  For games I'd say there's no reason whatever to use floating-point 
arithmetic.  It's slower and takes more memory, and lends very little 
benefit to this kind of work (lower roundoff error - big whoop).  I'd 
actually take the trouble to ensure that integer arithmetic was always 
being used, with casts and the like.

cheers
Michael Ashton


