Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Electrnica
Propuesta de prcticas
Curso 2014-2015
Curso 2014-2015
ndice de contenido
Algunas cosas tiles.............................................................................................................................3
Problemas detectados...........................................................................................................................8
Como empezar, generacin de un tono...............................................................................................12
Practica propuesta...............................................................................................................................14
Retraso en el tiempo...........................................................................................................................15
Prctica propuesta...............................................................................................................................16
Filtrado en el dominio del tiempo......................................................................................................17
Prctica propuesta...............................................................................................................................20
Filtrado en el dominio de la frecuencia..............................................................................................21
Prctica propuesta...............................................................................................................................26
2/26
Curso 2014-2015
Algunas cosas tiles
Antes de empezar hay una serie de funciones que son tiles tener en cuenta para poder trabajar con
la placa de desarrollo.
En el laboratorio hay disponibles en este momento dos sistemas de desarrollo, uno basado en el
DSP TMS320C6713 y el segundo basado en el procesador TMS320C6748.
El sistema de desarrollo proporciona una serie de funciones para acceder a los recursos de la placa.
Curso 2014-2015
sample_data = input_righ_sample(); //lee la muestra de la derecha,
16 bits
output_righ_sample(sample_data); // escribe la muestra de la
derecha, 16 bits
sample_data = input_sample(); //lee los dos canales, los 16 bits
ms significativos corresponden al canal izquierdo, 32 bits
output_sample(sample_data); // escribe los dos canales, los 16
bits ms significativos corresponden al canal izquierdo, 32 bits
Para acceder fcilmente a los dos canales se puede incluir en el cdigo la siguiente definicin:
typedef union {
Uint32 uint;
short channel[2];
} AICData;
Para usarla:
AICData myData;
myData. uint = input_sample();
y ahora acceder al canal izquierdo es suficiente con hacer
myData. channel [1] y para el derecho myData. Channel [0]
Compruebe que el modelo escogido es far, con esta placa, cualquier otro modelo provoca que las
interrupciones no se ejecuten.
4/26
Curso 2014-2015
En la figura puede observar donde se activa dicha opcin
5/26
Curso 2014-2015
void L138_initialise_intr(int32_t fs, int16_t adc_gain, int16_t
dac_atten, int8_t input_type)
Para trabajar con interrupciones EDMA, en este caso se establece un buffer y la interrupcin se
ejecuta cuando el buffer est lleno.
void L138_initialise_edma(int32_t fs, int16_t adc_gain, int16_t
dac_atten, int8_t input_type)
Todas estas funciones estn configuradas para que la interrupcin se resetea en escritura, lo que
obliga a escribir una muestra siempre, aunque esta muestra sea silencio, (0), es posible modificar
esto fcilmente modificando estas funciones
La configuracin de la entrada y la velocidad de muestreo son ahora parmetros de la funcin en
lugar de variables globales.
Aqui puede ver dos ejemplos de configuracin, uno con velocidad de muestreo de 8KHz y entrada
LINE y el segundo con una velocidad de 16KHz y entrada mic
L138_initialise_intr(FS_8000_HZ,ADC_GAIN_0DB,DAC_ATTEN_0DB,LCDK_LINE_INPUT);
L138_initialise_intr(FS_16000_HZ,ADC_GAIN_0DB,DAC_ATTEN_0DB,LCDK_MIC_INPUT);
CUIDADO
Un aspecto al que hay que prestar atencin, por los posibles problemas que puede provocar, es
fichero de configuracin CMD que establece el mapa de memoria de la placa. Cuando se inicia un
proyecto con Code Composer este establece un fichero de configuracin por defecto que no es
adecuando para ninguno de los sistemas de desarrollo, por lo que debe prestar atencin de que el
fichero de configuracin es correcto. En los ejemplos proporcionados para ambas plataformas, se
incluyen ya el fichero correcto, este fichero est en el directorio support donde tambin se
encuentran el fichero donde se incluye el cdigo con las funciones de configuracin y acceso a las
muestras (input_left_sample ... )que se han comentado anteriormente. El fichero para el
sistema c6713 se denomina C6713dsk.cmd, el fichero para el sistema basado en el c6748 se llama
linker_dsp.cmd
A continuacin se incluyen los contenidos de ambos ficheros.
Observe que el tamao del stack y del heap estn incluidas en el fichero del c6748, aunque ambas
opciones se pueden fijar en las opciones de proyecto.
Es importante que preste atencin al tamao del stack ya que las variables locales de las funciones,
incluidas las variables definidas dentro de la rutina main, se almacenan dentro del stack. Un stack
pequeo o estructuras locales muy grandes pueden provocar un desbordamiento del stack.
/*C6713dsk.cmd
MEMORY
{
IVECS:
IRAM:
SDRAM:
FLASH:
org=0h,
len=0x220
org=0x00000220,
len=0x0002FDE0 /*internal memory*/
org=0x80000000, len=0x01000000 /*external memory*/
org=0x90000000, len=0x00020000 /*flash memory*/
6/26
Curso 2014-2015
}
SECTIONS
{
.EXT_RAM
.vectors
.text
.bss
.cinit
.stack
.sysmem
.const
.switch
.far
.cio
.csldata
}
:>
:>
:>
:>
:>
:>
:>
:>
:>
:>
:>
:>
SDRAM
IVECS
IRAM
IRAM
IRAM
IRAM
IRAM
IRAM
IRAM
IRAM
IRAM
IRAM
/* linker_dsp.cmd */
-stack
-heap
0x00000800
0x00010000
MEMORY
{
dsp_l2_ram:
shared_ram:
external_ram:
}
SECTIONS
{
.text
.const
.bss
.far
.switch
.stack
.data
.cinit
.sysmem
.cio
.vecs
.EXT_RAM
}
>
>
>
>
>
>
>
>
>
>
>
>
ORIGIN = 0x11800000
ORIGIN = 0x80000000
ORIGIN = 0xC0000000
LENGTH = 0x00040000
LENGTH = 0x00020000
LENGTH = 0x08000000
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
dsp_l2_ram
external_ram
7/26
Curso 2014-2015
Problemas detectados
El objetivo de este apartado es ir incluyendo los problemas detectados en los sistemas de desarrollo,
por lo que esta seccin podr cambiar con el tiempo. Algunos de estos problemas son comunes en
ambas plataformas,
La interrupcin no se ejecuta.
Posibles causas.
Sistema 6713, el modelo de compilacin no es FAR.
Sistema 6748, Se ha detectado un problema con la interrupcin cuando la entrada est configurada
como LINE, este problema no aparece cuando se ejecuta el programa por primera vez pero cuando
se caga veces sucesivas la interrupcin no se ejecuta ms. Si se sufre este problema es necesario
modificar un fichero. En el fichero L138_init_aic3106_ini.c, la funcin
L138_init_aic3106_registers
if (input_type == LCDK_LINE_INPUT)
{
AIC3106_writeRegister( 19, 0x04 );
AIC3106_writeRegister( 22, 0x04 );
}
// power up ADCs
// and connect LINE1L/R to ADC
por
if (input_type == LCDK_LINE_INPUT)
{
AIC3106_writeRegister( 19, 0x04 );
AIC3106_writeRegister( 22, 0x04 );
AIC3106_writeRegister( 17, 0x0F );
0dB
AIC3106_writeRegister( 18, 0xF0 );
0dB
AIC3106_writeRegister( 25, 0x40 );
}
// power up ADCs
// and connect LINE1L/R to ADC
// 17 MIC3L to L ADC (default 0xFF, NC) 0x00
// 18 MIC3R to R ADC (default 0xFF, NC) 0x00
// 25 MICBIAS 0x40 2V, 0x00 OFF
Curso 2014-2015
Problema de depuracin, la ejecucin paso a paso en el depurador hace cosas raras, entra en
cdigo que no debe y parece que hace algo que no se corresponde con lo que veo en la pantalla
La causa ms comn de esto es que est activa alguna opcin de optimizacin de cdigo, en este
caso se debe deshabilitar. Seleccionar project->propierties. Seleccionar C6000 Compiler y escoger
Basic Options, tal como aparece en la figura. A continuacin en la opcin Optimization level
selecionar disable.
Recuerde que estos cambios son para depuracin, una vez que el cdigo est depurado y se pretenda
su despliegue en campo debe desactivarse las opciones de depuracin y seleccionar las opciones de
optimizacin de cdigo para que este sea ms eficiente y el programa generado sea de menor
tamao
Curso 2014-2015
int64_t resultado;
int32_t val1,val2;
resultado = val1*val2;
Si el resultado de la operacin de multiplicacin es mayor que el mayor valor que puede caber en un
entero de 32 bits se va a producir un truncamiento en el acumulador interno, con lo que el resultado
de la operacin ser errneo. Para evitar este problema se necesita usar casting
resultado = (int64_t)val1*(int64_t)val2;
Con esto, antes de multiplicar, se fuerza a pasar tanto val1 como val2 a enteros de 64 bits, con lo
que el sistema usar un acumulador de 64 bits internamente y se evitar el problema de
truncamiento.
Conversin entre tipos
Algo a lo que hay que prestar atencin, debido a las potenciales problemas que puede causar, es la
conversin entre tipos de datos.
Cuando se va a pasar de un tipo a otro hay tres operaciones a las que hay que prestar atencin por si
es preciso aplicarlas o evitar que ocurran pues pueden provocar errores. Estas operaciones son:
1. Truncamiento. Es la operacin de conversin por defecto cuando se pretende convertir un
nmero entero de mayor tamao (por ejemplo un entero de 32 bits) a uno de menor tamao
(por ejemplo 16 bits), en este caso se eliminan los bits ms significativos.
2. Desplazamiento hacia la derecha. Esta es la operacin que se debe aplicar para conservar la
fidelidad numrica cuando se trabaja con nmeros en formato Q (punto fijo), por ejemplo,
para poder pasar de un nmero en formato Q31 a un nmero en formato Q16, y consiste en
un desplazamiento a la derecha para desechar los bits menos significativos. Se usa en la
multiplicacin.
3. Saturacin. En este caso se comprueba si el valor est comprendido dentro de los mrgenes
que la variable puede almacenar. Si est comprendido se asigna el valor y en caso contrario
se asigna a la variable el valor mximo (o mnimo) que puede almacenar. Esta operacin se
aplica para pasar de valor flotante a entero. En caso de que el valor est fuera de los lmites
y se realice la conversin el resultado ser un valor incorrecto que introducir una fuerte
distorsin en la seal de salida (una distorsin mayor que la introducida por la saturacin).
Cuando se opera con flotantes no es necesario realizar ninguna operacin, los flotantes ajustan
dinmicamente su fidelidad de forma que, excepto la saturacin cuando se pasa a muestras enteras
para enviarlas a los conversores, no es preciso realizar ninguna otra operacin.
Lectura y escrituras de canales mono y estero
Las libreras que estamos usando proporcionan una serie de funciones que nos permiten, bien leer o
escribir un canal, bien los dos canales estreos. Es necesario entender como funciona estas
funciones. En realidad, todas las funciones leen o escriben los dos canales simultneamente, para
ello leen (o escriben) en un registro del DSP. Para la lectura no hay problemas, como es una lectura
de un registro, podemos leer el registro con la funcin input_sample() que leer y presentar el
10/26
Curso 2014-2015
valor del registro completo (los 16 bits menos significativos son de un canal y los 16 mas
significativos del otro canal) o usar las funciones input_right_sample(void) y
input_left_sample(void), estas funciones leeran el registro completo y harn el
truncado/desplazamiento adecuado para presentar cada canal. El problema est en la escritura
estero, si pretendemos escribir output_right_sample() y output_left_sample(), como ambas
funciones escriben sobre el mismo registro, se produce una sobre escritura del registro, con lo que
solo uno de los dos canales se enviar a la salida. En este caso es preciso usar la funcin
output_sample()
11/26
Curso 2014-2015
Como empezar, generacin de un tono
Este programa genera una seal sinusoidal que se enva al conversor. Esto se percibe como un tono
//sine_intr.c Sine generation using sin() function
#include <math.h>
#include "L138_LCDK_aic3106_init.h"
frequency = 1000.0;
amplitude = 10000.0;
theta_increment;
theta = 0.0;
Curso 2014-2015
output_left_sample((short)( (amplitude1*sin(theta1))+
(amplitude2*sin(theta2)));
Como puede observar, el programa usa la funcin para escribir usando una interrupcin en el
conversor. La funcin de inicializacin establece la interrupcin 4 como interrupcin del conversor.
Ahora es necesario relacionar la interrupcin 4 con la funcin de tratamiento de la interrupcin.
Esto se realiza mediante el fichero vector_intr.asm, que se lista a continuacin. Observe como se
indica que cuando se reciba la interrupcin 4 debe ejecutar la funcin _interrup4. Esta funcin est
definida en el cdigo c. Preste atencin que se usa el carcter _ antes del nombre de la funcin. Es
una convencin del ensamblador de TI para indicar que la funcin est definida en otro lenguaje
distinto del ensamblador.
.global _vectors
.global _c_int00
.global _vector1
.global _vector2
.global _vector3
.global _interrupt4 ; funcion de tratamiento de la interrupcion
4
.global
.global
.global
.global
.global
.global
.global
.global
.global
.global
.global
_vector5
_vector6
_vector7
_vector8
_vector9
_vector10
_vector11
_vector12
_vector13
_vector14
_vector15
13/26
Curso 2014-2015
Practica propuesta
Usando los DIP (la funcin para leer el estado de los DIP es read_LCDK_user_DIP ) cree un
programa capaz de generar 4 tonos superpuestos seleccionables a travs de los DIPs 0 a 3 y con
frecuencias 500, 1000, 2000, 3000 Hercios.
Para ver si estn activos los distintos interruptores se puede usar el cdigo que aparece a
continuacin.
uint8_t aux = read_LCDK_user_DIP();
if ( aux & 0x1) // interruptor 1
.
if ( aux & 0x2) // interruptor 2
.
if ( aux & 0x4) // interruptor 3
.
if ( aux & 0x8) // interruptor 4
..
Los interruptores configurables en el sistema C6748 son los que aparecen en la placa numerados del
5 al 8, (el nmero 5 en la placa corresponde al interruptor 1 en el cdigo C).
Tenga en cuenta para esta prctica el ancho de banda impuesto por el conversor para escoger la
frecuencia adecuada
14/26
Curso 2014-2015
Retraso en el tiempo
Un ejercicio sencillo de implementar en sistemas digitales es introducir pequeos retrasos
temporales en la secuencia de los datos.
Para conseguir esto es necesario almacenar los datos en memoria para posteriormente presentarlos.
La manera ms simple de introducir este retraso es usando un buffer circular.
Es fcil calcular el tamao que debe tener el buffer para un determinado retraso temporal en funcin
de la frecuencia de muestreo. Por ejemplo si la frecuencia de muestreo es 8 KHz, el tamao del
buffer para conseguir un retraso de 1 segundo ser 1*8000.
Fjese en el uso de la directiva pragma DATA_SECTION para colocar el buffer en la memoria
externa. El proyecto necesita un fichero CMD para indicar que el segmento EXT_RAM se
encuentra en la memoria SDRAM. Las seccin debe estar definida o bien en fichero de
configuracin de DSPBIOS o en el fichero CMD. En el directorio Support pueden encontrar un
fichero CMD que define una seccin en la memoria externa llamada EXT_RAM. Preste atencin al
carcter . que se aade antes del nombre en la directiva DATA_SECTION.
#define MAX_BUF_SIZE 8000 //set maximum length of delay
short buffer[MAX_BUF_SIZE]; //storage for previous samples
short input;
int i = 0; //index into buffer
#pragma DATA_SECTION(buffer, .EXT_RAM)
#include "L138_LCDK_aic3106_init.h"
interrupt void interrupt4() //interrupt service routine
{
input = input_left_sample(); //read new input sample from ADC
output_left_sample(buffer[i]);
buffer[i] = input; //store new input and
//fraction of delayed value
if(++i >= MAX_BUF_SIZE) //test for end of buffer
i = 0;
return; //return from ISR
}
void main()
{
memset(buffer,0,sizeof(short)* MAX_BUF_SIZE);
L38_initialise_intr(FS_8000_HZ,ADC_GAIN_0DB,DAC_ATTEN_0DB,LCDK_MIC
_INPUT);
while(1); //infinite loop
}
15/26
Curso 2014-2015
Prctica propuesta
Para esta prctica el alumno implementar un ECO funcionando en estreo, la implementacin del
ECO se basa en el uso de un retardo junto con una realimentacin de la muestra actual y la antigua
atenuada.
N
iti
i=0
16/26
Curso 2014-2015
Filtrado en el dominio del tiempo.
Preste atencin que en cdigo presentado en este ejemplo solo se est filtrando un canal.
Sistema C6748
#include "L138_LCDK_aic3106_init.h"
#include "lp33.cof"
float yn;
//filter output
float x[N];
//filter delay line
interrupt void interrupt4()
{
short i;
for (i=(N-1) ; i>0 ; i--)
//shuffle delay line contents
x[i] = x[i-1];
//I know it's inefficient
x[0] = (float)(input_left_sample()); //get new input into delay
line
yn = 0.0;
//initialise filter output
for (i=0 ; i<N ; i++)
//calculate filter output
yn += h[i]*x[i];
output_left_sample((short)(yn));
return;
//output to codec
}
void main()
{
for (i=0 ; i<N ; i++)
//init values
x[i] = 0;
L38_initialise_intr(FS_8000_HZ,ADC_GAIN_0DB,DAC_ATTEN_0DB,LCDK_MIC
_INPUT);
while(1); //infinite loop
}
En estos ejemplos la lnea de retardo se ha realizado mediante un bucle for, que es claramente
ineficiente.
Una ms eficiente implementacin es usando memmove
memmove(x+1,x,sizeof(float)*(N-1));
Finalmente, es posible usar las funciones de la librera DSPLIB, una librera altamente optimizada
en ensamblador.
La funcin base es la siguiente
void DSPF_sp_fir_gen(const float * restrict x, const float *
restrict h, float restrict r, int nh, int nr)
17/26
Curso 2014-2015
donde x son la muestras de entrada, h el filtro (los coeficientes deben estar en orden inverso), r es el
resultado, nh es el tamao de h y nr es el tamao de r, el tamao de las muestras de entrada debe ser
nr+nh1.
Esto implica que esta funcin trabaja con bloques de muestras en lugar de muestra a muestra como
hemos hecho hasta el momento
float x[NR+NH-1];
float h[NH]
float y[NR]
// necesario
#pragma DATA_ALIGN(x, sizeof(float))
#pragma DATA_ALIGN(h, sizeof(float))
#pragma DATA_ALIGN(y, sizeof(float))
void interrupt4()
{
x[cont+NH-1] = (float)(input_left_sample());
output_left_sample((short)(y[cont]));
cont ++;
if (cont > NR)
{
DSPF_sp_fir_gen(x,h,y, NH, NR);
cont = 0;
for (i = 0; i < NH;i++) x[i] = x[NH+i-1];
}
return;
}
//Delay
18/26
Curso 2014-2015
x[0]
y1 =
y2 =
yn =
19/26
Curso 2014-2015
Prctica propuesta
A partir de los ejemplos anteriores cree un programa que sea capaz de actuar como ecualizador de 2
bandas (2 filtros en cascada) en punto fijo. Usando los DIPs 0 y 1 debe ser posible seleccionar que
filtro se activa.
Si est desarrollando en un sistema basado en el DSP C6748 ignore la configuracin de los LED ya
que el sistema no proporciona en este momento funciones para la modificacin de los leds.
Los filtros a usar sern un paso bajo hasta una frecuencia de corte de 2000 Hz y un paso alto con
una frecuencia de corte inferior de 1000Hz.
Para generar los filtros puede usar la herramienta de matlab FDATOOLS, disear el filtro y exportar
los coeficientes del filtro. Exporte los coeficientes tanto en formato int32 como en formato float y
genere un fichero h con cada uno de ellos. Ser necesario editar los ficheros de cabecera y cambiar
los tipos de los datos a float para el caso de los flotantes y a Int32 para el caso de los enteros.
Verifique que los filtros con ambos conjuntos de coeficientes funcionan igual, en caso negativo
justifique la razn.
A continuacin nada mas exportar los coeficientes enteros convierta los enteros de 32 bits a enteros
de 16 bits y compruebe en este caso el resultado. Justifique la razn de la diferencia entre operar
con enteros de 16 y enteros de 32
Para convertir los coeficientes a enteros de 32 es necesario quedarse con la parte mas significativa
para esto haremos la operacin de desplazamiento a la izquierda val >>=16;
Como mejora opcional se puede usar un mdulo gel para controlar la ganancia de cada filtro.
20/26
Curso 2014-2015
Filtrado en el dominio de la frecuencia
Para este ejemplo usaremos las funciones de librera
cfftr2_dit y icfftr2_dit
Estas funciones estn implementadas en ensamblador y est disponibles
Una cosa que hay que hay que tener en cuenta que la FFT debe ser calculada con un nmero par de
muestras y que hasta que no estn todas no es posible calcularlas. Esto implica dos cosas, la
necesidad de trabajar con varios bufferes, un buffer de proceso y un buffer donde se estn
almacenando las muestras, y el algoritmo debe cambiar uno por otro una vez que el buffer de estan
almacenando las muestras se ha llenado. As mimo, esto implica que el resultado se va a presentar
con un cierto retraso, este retraso ser mayor cuanto mayor sea el buffer
#define RADIX 2
#define DELTA (2*PI)/PTS
typedef struct Complex_tag {float real,imag;} COMPLEX;
// Importante, es preciso que los datos estn alineados para poder
pasar la
// informacin a funciones implementadas en ensamblador
//
#pragma DATA_ALIGN(W,sizeof(COMPLEX))
#pragma DATA_ALIGN(samples,sizeof(COMPLEX))
#pragma DATA_ALIGN(h,sizeof(COMPLEX))
COMPLEX W[PTS/RADIX] ;
//twiddle array
COMPLEX samples[PTS];
COMPLEX h[PTS];
COMPLEX bass[PTS], mid[PTS], treble[PTS];
short buffercount = 0;
samples
float iobuffer[PTS/2];
float overlap[PTS/2];
short i;
//index variable
short flag = 0;
float a, b;
Curso 2014-2015
short iTwid[PTS/2] ;
float bass_gain = 1.0;
//ISR
{
output_left_sample((short)(iobuffer[buffercount]));
iobuffer[buffercount++] = (float)((short)input_left_sample());
// PRESTE ATENCIO, SOLO LA MITAD
if (buffercount >= PTS/2)
iobuffer
}
}
main()
{
digitrev_index(iTwid, PTS/RADIX, RADIX);
for( i = 0; i < PTS/RADIX; i++ )
{
W[i].real = cos(DELTA*i);
W[i].imag = sin(DELTA*i);
}
bitrev(W, iTwid, PTS/RADIX);
//bit reverse W
Curso 2014-2015
treble[i].real = 0.0;
treble[i].imag = 0.0;
}
{
bass[i].real = lpcoeff[i];
//lowpass coeff
mid[i].real =
//bandpass coeff
bpcoeff[i];
treble[i].real = hpcoeff[i];
//highpass coef
}
//
//
//Esto es la gracia de la FFT puedo hacer la transformada de los
filtros al principio con lo cual no es necesario hacerlo mas, solo
es preciso hacer la transformada de los datos
cfftr2_dit(bass,W,PTS);
cfftr2_dit(mid,W,PTS);
cfftr2_dit(treble,W,PTS);
comm_intr();
while(1)
{
while (flag == 0);
completo
flag = 0;
for (i=0 ; i<PTS/2 ; i++)
{
samples[i].real = iobuffer[i]; // copia los datos de
entrada a al buffer que se va a usar
iobuffer[i] = overlap[i];
overlaped
}
23/26
Curso 2014-2015
for (i=0 ; i<PTS/2 ; i++)
{
cfftr2_dit(samples,W,PTS);
// Como se puede observar, ahora el bucle es menor, no como en
caso del dominio del tiempo donde tenemos tantos bucles como
filtros bucles
for (i=0 ; i<PTS ; i++)
{
//frequency-domain
//complex multiply samples by h
a = samples[i].real;
b = samples[i].imag;
samples[i].real = h[i].real*a - h[i].imag*b;
samples[i].imag = h[i].real*b + h[i].imag*a;
}
icfftr2_dif(samples,W,PTS); // transformada discreta
for (i=0 ; i<PTS ; i++)
samples[i].real /= PTS;
for (i=0 ; i<PTS/2 ; i++)
Curso 2014-2015
overlap[i] += samples[i].real;
}
}
25/26
Curso 2014-2015
Prctica propuesta
Usando las especificaciones de la prctica anterior realice ahora el filtrado usando la convolucin en
el dominio de la frecuencia. A fin de simplificar el sistema cree ahora los coeficientes en punto
flotante. Si lo desea puede usar la FFT implementada en cdigo C que se puede bajar del campus
virtual.
Verifique la velocidad de operacin y comprela con el filtro FIR en flotante
26/26