//**************************************************************************
//*                     This file is part of the                           *
//*                      Mpxplay - audio player.                           *
//*                  The source code of Mpxplay is                         *
//*        (C) copyright 1998-2006 by PDSoft (Attila Padar)                *
//*                    http://mpxplay.cjb.net                              *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  This program is distributed in the hope that it will be useful,       *
//*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function: surround (wide stereo) effect (for 2 channels only!)

#include "au_mixer.h"
#include "newfunc\newfunc.h"

int MIXER_var_surround;

static void mixer_surround_lq(struct mpxplay_audioout_info_s *aui)
{
 short *pcms=aui->pcm_sample;
 unsigned int i=aui->samplenum,step=aui->chan_card;

 i/=step;
 do{
  int cadd=  (int)pcms[0]+(int)pcms[1];
  int csub=(((int)pcms[0]-(int)pcms[1])*MIXER_var_surround)/100;
  int c1;

  c1=(cadd+csub)/2;
  if(c1>MIXER_SCALE_MAX)
   c1=MIXER_SCALE_MAX;
  else
   if(c1<MIXER_SCALE_MIN)
    c1=MIXER_SCALE_MIN;
  pcms[0]=c1;

  c1=(cadd-csub)/2;
  if(c1>MIXER_SCALE_MAX)
   c1=MIXER_SCALE_MAX;
  else
   if(c1<MIXER_SCALE_MIN)
    c1=MIXER_SCALE_MIN;
  pcms[1]=c1;

  pcms+=step;
 }while(--i);
}

static void mixer_surround_hq(struct mpxplay_audioout_info_s *aui)
{
 PCM_CV_TYPE_F *pcm=(PCM_CV_TYPE_F *)aui->pcm_sample;
 unsigned int i=aui->samplenum,step=aui->chan_card;
 const float cfsur=(float)MIXER_var_surround/200;
 const float half=0.5;
 i/=step;
 do{
  const PCM_CV_TYPE_F cadd=(pcm[0]+pcm[1])*half;
  const PCM_CV_TYPE_F csub=(pcm[0]-pcm[1])*cfsur;
  pcm[0]=(cadd+csub);
  pcm[1]=(cadd-csub);
  pcm+=step;
 }while(--i);
}

static int mixer_surround_checkvar(struct mpxplay_audioout_info_s *aui)
{
 if((MIXER_var_surround!=100) && (aui->chan_card>=2))
  return 1;
 return 0;
}

one_mixerfunc_info MIXER_FUNCINFO_surround={
 "MIX_SURROUND",
 "mxsr",
 &MIXER_var_surround,
 MIXER_INFOBIT_EXTERNAL_DEPENDENCY, // aui->chan_card
 10,500,100,10,
 NULL,
 &mixer_surround_lq,
 &mixer_surround_hq,
 &mixer_surround_checkvar,
 NULL
};
