Mail Archives: djgpp/1999/08/18/03:57:05
Adding the samples is the only way to properly mix two sounds. It is
fine to scale each sample stream, but each of the various streams will
then have a reduced volume.
In terms of a real-time mixing system with multiple channels (probably
fixed number, but not necessarily) this wouldn't be so bad, as a sound
by itself should be the same volume as when it was played together
with other sounds - just so long as a constant scaling rate was used.
If, however, when one sound is playing it is played at full volume,
yet when two are playing they are scaled by a factor of 50%, then the
two will sound noticably quieter.
Davin.
On Tue, 17 Aug 1999 02:19:54 +0700, Batchex <thedark1 AT Phreaker DOT net>
wrote:
[...]
>produce a "wick" or a "whack". For that reason, I listed a few ways to
>mix sounds and prevent clipping (theoretically, note that I haven't
>got the time to test these approaches yet, so tell me if it works).
>
>Assuming 8 bit, signed data format. Length is the length of the
>longest sound file that is to be mixed.
>
>1. Scale each samples with a certain values before adding them
>together. The sum of all scale values must be 1.
>ex.1 : two channels (sound files), each channels is weighted 0.5 (the
>sum of all weights is 0.5 + 0.5 =1).
>
> for(i=0;i<length;i++)
> mixed[i] = (channel1[i]*0.5) + (channel2[i]*0.5) + 0.5;
>
>
>2. Add the samples from each channels together, scan the min and max
>values of the resulting buffer, then scale the all the samples
>resulted from the mixing with the ratio of the max (or abs(min), which
>ever the greater) of the scanned sample values and the max value the
>data format supports.
>ex.2: data format is 8 bit signed, so the min value the data format
>supports is -128, and the max is 127.
>
> int buffer[length];
> int sampleMax, sampleMin;
> float scale;
>
> sampleMin = 2147483647;
> sampleMax = -2147483678;
>
> for(i=0;i<length;i++)
> {
> buffer[i] = channel1[i] + channel2[i];
> if(buffer[i] < sampleMin) sampleMin = buffer[i];
> if(buffer[i] > sampleMax) sampleMax = buffer[i];
> }
>
> if((sampleMax+sampleMin) >= 0) scale = sampleMax / 127;
> else scale = sampleMin / 128;
>
> for(i=0;i<length;i++)
> buffer[i] = (int)((buffer[i] * scale) + .5);
>
>
>3. The approach no 2 can be simplified if there is a fixed number of
>channels to be mixed. The result of the addition of each samples from
>each channels is scaled by 1/number of channels.
>ex.3: number of channels is 4, so the scale value is 1/4 or 0.25.
>
> for(i=0;i<length;i++)
> {
> buffer[i] = channel1[i] + channel2[i] + channel3[i] +
> channel4[i];
> buffer[i] = (int)((buffer[i] * 0.25) + 0.5);
> }
>
>
>Hope that helps.
>
>Batchex
>mailto:thedark1 AT Phreaker DOT net
>
>
__________________________________________________________
*** davmac - sharkin'!! davmac AT iname DOT com ***
my programming page: http://yoyo.cc.monash.edu.au/~davmac/
- Raw text -