Logo Search packages:      
Sourcecode: yiff version File versions  Download package

bufmix.c

#include <stdio.h>
#include "ysound.h"


void YiffMixBuffers(
      Audio *audio,
      SoundBuffer *tar_buf, const SoundBuffer *src_buf,
      YDataLength len,
      Coefficient volume_left, Coefficient volume_right
);

void YiffShortenBuffer16(
      u_int16_t *buf,
      int buf_len,            /* In u_int8_t (not u_int16_t) units. */
      int buf_shoren_len
);
void YiffShortenBuffer8(
      u_int8_t *buf,
      int buf_len,            /* In u_int8_t units. */
      int buf_shoren_len
);


#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define ABSOLUTE(x)     (((x) < 0) ? ((x) * -1) : (x))


/*
 *    Mixes the source buffer to the target buffer and
 *    compensates for volume.
 */
void YiffMixBuffers(
      Audio *audio,
      SoundBuffer *tar_buf, const SoundBuffer *src_buf,
      YDataLength len,
      Coefficient volume_left,
      Coefficient volume_right
) 
{
      int i, b, blocks;
      SoundBuffer *tp;
      const SoundBuffer *sp;
      Coefficient lc, rc;
      Boolean flip;

   
      if((audio == NULL) ||
         (tar_buf == NULL) ||
         (src_buf == NULL) ||
         (len <= 0)
      )
          return;

      flip = audio->flip_stereo;

      /* Calculate coefficients. */
      if(audio->channels == 2)
      {
          /* Stereo. */
          blocks = 2;

          /* Calculate left and right coefficients. */
          lc = MAX(MIN(volume_left, 1), 0);
          rc = MAX(MIN(volume_right, 1), 0);
      }
      else
      {
          /* Mono. */
          blocks = 1;

          /* Average left and right coefficients. */
          lc = (volume_left + volume_right) / 2;

          rc = MAX(MIN(lc, 1), 0);
          lc = rc;
      }

      /* Begin buffer mixing. */
      for(i = 0, b = 0, tp = tar_buf, sp = src_buf;
          i < len;
          i++, tp++, sp++
      ) 
      {
          /* Is source byte positive or negative? */
          if(*sp < 0)
          {
            /* Source byte is negative. */

            if(b == 0)
                (*tp) = MAX((int)(*tp) +
                  ((int)(*sp) * ((flip) ? rc : lc)),
                  (int)-128
                );
            else
                (*tp) = MAX((int)(*tp) +
                  ((int)(*sp) * ((flip) ? lc : rc)),
                  (int)-128
                );
          }
          else
          {
            /* Source byte is positive. */

            if(b == 0)
                (*tp) = MIN((int)(*tp) +
                  ((int)(*sp) * ((flip) ? rc : lc)),
                  (int)127
                );
            else
                (*tp) = MIN((int)(*tp) +
                  ((int)(*sp) * ((flip) ? lc : rc)),
                  (int)127
                );
          }

          /* Increment block position b. */
          b++;
          if(b >= blocks)
            b = 0;
      }
}

/*
 *    Moves the samples (shortens) from the given buffer length
 *    to the shorten length.
 *
 *    Inputs assumed valid (not NULL and greater than 0).
 *
 *    Make sure the buffer is even number when allocated!
 */
void YiffShortenBuffer16(
      u_int16_t *buf,
      int buf_len,      /* In u_int8_t (not u_int16_t) units. */
      int buf_shoren_len
)
{
      u_int16_t   *tar_ptr = buf,
                  *src_ptr = buf,
                  *tar_end = buf + (buf_shoren_len / 2);

      int   src_pos = 0,      /* Pos and inc in units of * 256. */
            src_inc = 256 * buf_len / buf_shoren_len;

      /* Target length is assumed to be shorter than source len. */
      while(tar_ptr < tar_end)
      {
          *tar_ptr++ = src_ptr[(src_pos >> 8)];
          src_pos += src_inc;
      }                
}

/*
 *      Moves the samples (shortens) from the given buffer length
 *      to the shorten length.
 *
 *      Inputs assumed valid (not NULL and greater than 0).
 */
void YiffShortenBuffer8(
      u_int8_t *buf,
      int buf_len,      /* In u_int8_t units. */
      int buf_shoren_len
)
{
      u_int8_t    *tar_ptr = buf,
                  *src_ptr = buf,
                  *tar_end = buf + buf_shoren_len;

      int   src_pos = 0,      /* Pos and inc in units of * 256. */
            src_inc = 256 * buf_len / buf_shoren_len;

      /* Target length is assumed to be shorter than source len. */
      while(tar_ptr < tar_end)
      {
          *tar_ptr++ = src_ptr[(src_pos >> 8)];
          src_pos += src_inc;
      }
}

Generated by  Doxygen 1.6.0   Back to index