From: DavMac AT iname DOT com (Davin McCall) Newsgroups: comp.os.msdos.djgpp Subject: Re: 8-Bit Clipping Date: Wed, 18 Aug 1999 03:19:43 GMT Organization: Monash Uni Lines: 88 Distribution: world Message-ID: <37ba254f.9723519@newsserver.cc.monash.edu.au> References: <37B46FE9 DOT 87C3B20D AT geocities DOT com> <1097 DOT 990817 AT Phreaker DOT net> NNTP-Posting-Host: damcc5.halls.monash.edu.au X-Trace: towncrier.cc.monash.edu.au 934946329 152 130.194.198.138 (18 Aug 1999 03:18:49 GMT) X-Complaints-To: abuse AT monash DOT edu DOT au NNTP-Posting-Date: 18 Aug 1999 03:18:49 GMT X-Newsreader: Forte Free Agent 1.1/32.230 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com 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 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 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 { > 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 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 { > 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/