Sound mixing

From: Andreas Schiffler <schiffler_at_no.spam.please>
Date: Fri Sep 24 1999 - 06:16:23 CST

Hi folks,

thanks for all your good comments on sound-mixing. Its working now and
the reason why I had problems, was that I mixed "unsigned char" and
"char" types in the code without knowing it.

First of all, the whole discussion on linear vs. non-linear did not seem
to be of much importance in practice. Basically all soundcards these
days work with a linear scale by default (alhough it might not be
completely linear in physical reality) and so does /dev/dsp for a
standard OSS setup.

Mixing is done simply by adding signals. Care has to be taken to do this
addition at a higher bit-resolution, with signed variables and with a
clipping stage applied after addition. In my case (unsigned 8bit
samples) the code lookes something like this ...

Samples are preprocessed with "sox" ...
sox infile.wav -c 1 -r 22050 -t ub - >outfile.raw

After loading the sample ...
 /* Process buffer: unsigned to signed */
 curpos=ga->samples[sample_id].data;
 for (i=0; i<ga->samples[sample_id].length; i++) {
  *curpos ^= 0x80;
  curpos++;
 }

The mixing loop goes like this ...

 char *curpos

 /* Clear playbuffer (signed 0) */
 memset(playbuffer,0,AUDIO_BUFFER_SIZE);

#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))

  /* Loop over playbuffer in curpos */
   /* Loop over all samples to be mixed */
     /* Mix-in current sample */
     if (*curplaying->curpos<0) {
      *curpos = MAX((int)*curpos + (int)*curplaying->curpos,(int)-128);
     } else {
      *curpos = MIN((int)*curpos + (int)*curplaying->curpos,(int)127);
     }

  /* Signed to unsigned */
  (unsigned char)*curpos = (char)*curpos + 128;

I've wrapped everything up in a sight little library (libgaudio) that
allows for playback of samples using simple triggers in a background
thread - I use it my new game (soon to be release to the public). If
anyone cares to have a look at it or test it, send email and I forward a
copy.

Ciao
Andreas

-
Saskatoon Linux Group Mailing List.
-
To unsubscribe, send mail to
'linux-request@slg.org' with
'unsubscribe' in the body.
Received on Fri Sep 24 06:16:23 1999

This archive was generated by hypermail 2.1.8 : Sun Jan 09 2005 - 13:53:59 CST