main.c File Reference


Detailed Description

AEC.

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file CONCEPTION/AEC/main.c.

#include <stdio.h>
#include <string.h>

Go to the source code of this file.

Defines

#define BLOCK_SIZE   64
#define NUM_TAPS   256
#define ROUND_DIV(a, b)   (((a) + ((b)/2))/(b))
#define SQ(x)   ((x)*(x))

Functions

void echo_cancel (const short *out_buf, const short *in, size_t block_size, int *filter_q16, size_t num_taps, short *echo_cancelled_in)
int main (int argc, char *_argv[])


Define Documentation

#define BLOCK_SIZE   64

Definition at line 53 of file CONCEPTION/AEC/main.c.

Referenced by main().

#define NUM_TAPS   256

Definition at line 52 of file CONCEPTION/AEC/main.c.

Referenced by main().

#define ROUND_DIV ( a,
 )     (((a) + ((b)/2))/(b))

Definition at line 50 of file CONCEPTION/AEC/main.c.

Referenced by echo_cancel().

#define SQ (  )     ((x)*(x))

Definition at line 49 of file CONCEPTION/AEC/main.c.

Referenced by echo_cancel().


Function Documentation

void echo_cancel ( const short *  out_buf,
const short *  in,
size_t  block_size,
int *  filter_q16,
size_t  num_taps,
short *  echo_cancelled_in 
)

Definition at line 55 of file CONCEPTION/AEC/main.c.

References ROUND_DIV, and SQ.

Referenced by main().

00056 {
00057     const short *cur_out = &out_buf[block_size-1];
00058     const short *cur_in = &in[block_size-1];
00059     short *cur_in_ec = &echo_cancelled_in[block_size-1];
00060     
00061     const short *out_p;
00062     int out_norm_sq_p16; /* The value is * 2^16 */
00063 
00064     /* Calculate initial norm squared of output vector */
00065     out_norm_sq_p16 = 0;
00066     for (out_p = &out_buf[block_size+num_taps-1]; out_p != &out_buf[block_size-1]; --out_p)
00067         out_norm_sq_p16 += SQ(ROUND_DIV((int) *out_p, 1 << 8));
00068 
00069     do
00070     {
00071         int *filter_q16_p;
00072         int echo_est_q16;
00073         short echo_est;
00074 
00075         /* Caculate echo estimate for this sample using output data  */
00076         echo_est_q16 = 0;
00077         for (out_p = &cur_out[num_taps-1], filter_q16_p = &filter_q16[num_taps-1]; out_p != cur_out; --out_p, --filter_q16_p)
00078             echo_est_q16 += (int) (*out_p)*(*filter_q16_p);
00079 
00080         echo_est = ROUND_DIV(echo_est_q16, 1 << 16);
00081 
00082         /* Echo cancelled input is simply input minus echo estimate
00083                        * Round echo_est_q16 to nearest int when convering to short
00084                        * This can also be interpreted as the error term, which
00085                        * is used for the NLMS correction below
00086                        */
00087         *cur_in_ec = *cur_in - echo_est;
00088 
00089         /* Update norm squared of output vector */
00090         out_norm_sq_p16 += SQ(ROUND_DIV((int) cur_out[0], 1<<8)) - SQ(ROUND_DIV((int) cur_out[num_taps], 1<<8));
00091 
00092         /* Update filter tap weights using NLMS correction */
00093         if (out_norm_sq_p16 != 0)
00094         {
00095             for (out_p = &cur_out[num_taps-1], filter_q16_p = &filter_q16[num_taps-1]; out_p != cur_out; --out_p, --filter_q16_p)
00096                 *filter_q16_p += ROUND_DIV((int) *cur_in_ec * (int) *out_p, out_norm_sq_p16);
00097         }
00098     } while (cur_out--, cur_in_ec--, cur_in-- != in);
00099 }

int main ( int  argc,
char *  _argv[] 
)

Definition at line 102 of file CONCEPTION/AEC/main.c.

References BLOCK_SIZE, echo_cancel(), and NUM_TAPS.

00103 {
00104   short out_buf[BLOCK_SIZE+NUM_TAPS];
00105   int filter_q16[NUM_TAPS];
00106 
00107   memset(out_buf, 0, sizeof (out_buf));
00108   memset(filter_q16, 0, sizeof (filter_q16)); // The filter tap weights must
00109                                               // initially be zero!!
00110 
00111   while (!kbhit())
00112   {
00113     short in[BLOCK_SIZE];
00114     short echo_cancelled_in[BLOCK_SIZE];
00115 
00116     // Output BLOCK_SIZE samples to the speaker from outBuf and input 
00117     // BLOCK_SIZE samples into inBuf from the microphone.
00118     play_record_local(outBuf, in, BLOCK_SIZE);
00119 
00120     // Cancel the echo of out present on in using the outBuf buffered
00121     // samples.  Adaptively updates the filter tap weights as it goes.
00122     echo_cancel(out_buf, in, BLOCK_SIZE, filter_q16, NUM_TAPS, echo_cancelled_in);
00123 
00124     // Shift samples in preparation to get more data...
00125     memmove (&amp; out_buf[BLOCK_SIZE], &out_buf[0], sizeof (out_buf) - sizeof (in));
00126 
00127     // Send the echo cancelled input and receive to/from remote source
00128     play_record_remote(echo_cancelled_in, out, BLOCK_SIZE);
00129   }
00130 }


Generated on Fri Feb 19 02:23:20 2010 for AVR32 UC3 - EVK1104 DSPLib Demo Documentation by  doxygen 1.5.5