c - Is this filter implementation making correct output? -


i want make finite impulse response fixedpoint arithmetic. put program i'm not sure it's correct:

    #include <stdio.h>     #include "system.h"      #define fbits 16 /* number of fraction bits */     const int c0 = (( 299<<fbits) + 5000) / 10000; /* (int)(0.0299*(1<<fbits) + 0.5) */     const int c1 = ((4701<<fbits) + 5000) / 10000; /* (int)(0.4701*(1<<fbits) + 0.5) */     /* ditto c3 , c2 */     const int c2 = (( 4701<<fbits) + 5000) / 10000; /* (int)(0.4701 *(1<<fbits) + 0.5) */     const int c3 = ((299<<fbits) + 5000) / 10000; /* (int)(0.299*(1<<fbits) + 0.5) */      #define half (1 << (fbits) >> 1) /* half adjust rounding = (int)(0.5 * (1<<fbits)) */     signed char input[4]; /* 4 recent input values */      char get_q7( void );     void put_q7( char );      void firfixed()     {      int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];      signed char output = (signed char)((sum + half) >> fbits);      put_q7(output);     }      int main( void )     {            int i=0;         int a;         while(1)         {              (a = 3 ; > 0 ; a--)         {           input[i] = input[i-1];         }                input[0]=get_q7();                     firfixed();          i++;               }          return 0;     }    #include <sys/alt_stdio.h>  char get_q7( void );  char prompt[] = "enter q7 (in hex-code): "; char error1[] = "illegal hex-code - character "; char error2[] = " not allowed"; char error3[] = "number big"; char error4[] = "line long"; char error5[] = "line short";  char get_q7( void ) {     int c; /* current character */     int i; /* loop counter */     int num;     int ok = 0; /* flag: 1 means input accepted */      while( ok == 0 )     {         num = 0;         for( = 0; prompt[i]; += 1 )             alt_putchar( prompt[i] );          = 0; /* number of accepted characters */         while( ok == 0 )         {             c = alt_getchar();             if( c == (char)26/*eof*/ ) return( -1 );             if( (c >= '0') && (c <= '9') )             {                 num = num << 4;                 num = num | (c & 0xf);                 = + 1;             }             else if( (c >= 'a') && (c <= 'f') )             {                 num = num << 4;                 num = num | (c + 10 - 'a');                 = + 1;             }             else if( (c >= 'a') && (c <= 'f') )             {                 num = num << 4;                 num = num | (c + 10 - 'a');                 = + 1;             }             else if( c == 10 ) /* lf finishes line */             {                 if( > 0 ) ok = 1;                 else                 {    /* line short */                     for( = 0; error5[i]; += 1 )                         alt_putchar( error5[i] );                     alt_putchar( '\n' );                     break; /* ask new number */                 }             }             else if( (c & 0x20) == 'x' || (c < 0x20) )             {                 /* ignored - nothing special */             }             else             {   /* illegal hex-code */                 for( = 0; error1[i]; += 1 )                     alt_putchar( error1[i] );                 alt_putchar( c );                 for( = 0; error2[i]; += 1 )                     alt_putchar( error2[i] );                 alt_putchar( '\n' );                 break; /* ask new number */             }             if( ok )             {                 if( > 10 )                 {                     alt_putchar( '\n' );                     for( = 0; error4[i]; += 1 )                         alt_putchar( error4[i] );                     alt_putchar( '\n' );                     ok = 0;                     break; /* ask new number */                 }                 if( num >= 0 && num <= 255 )                     return( num );                 for( = 0; error3[i]; += 1 )                     alt_putchar( error3[i] );                 alt_putchar( '\n' );                 ok = 0;                 break; /* ask new number */             }         }     }     return( 0 ); /* dead code, or compiler complains */ } #include <sys/alt_stdio.h>  void put_q7( char );    /* prototype */  char prom[] = "calculated fir-value in q7 (in hex-code): 0x";  char hexasc (char in)   /* function */ {     in = in & 0xf;     if (in <=9 ) return (in + 0x30);     if (in > 9 ) return (in - 0x0a + 0x41);     return (-1); }  void put_q7( char inval) {     int i; /* loop counter */            for( = 0; prom[i]; += 1 )             alt_putchar( prom[i] );     alt_putchar (hexasc ((inval & 0xf0) >> 4));     alt_putchar (hexasc (inval & 0x0f));     alt_putchar ('\n');      } 

when run i'm not sure whether currect results, can me verify or change program if has done?

the fir-filter receives , sends 8-bit fixed-point numbers in q7-format via standard input , output. remember output measured time (number of ticks) in hex format. following guidelines presented in previous section, program should call getchar() read q7-value. should call putchar() write q7-value.

the coefficients are

c0=0.0299 c1=0.4701 c2=0.4701 c3=0.299

i got here i'm not sure whether complete , still have questions answer: fixedpoint fir filter in c?

can tell me if program correct?

judging information on q (number format) @ wikipedia, constants not correct.

you mention q7 format, corresponds signed fractional number 7 fractional bits (for 8 bits in total). represent +0.0299 q7 value, you'd multiply 0.0299 128, yielding 3.8272, rounded 4. representation of +0.0299 q7 number 4. similarly, +0.4701, exact value 60.1728, represented 60.

the first part of firfixed() function fine. division, though, needs 128, , 'half' 64. thus, think end with:

const int c0 = (0.0299 * 128 + 0.5); const int c1 = (0.4701 * 128 + 0.5); const int c2 = (0.4701 * 128 + 0.5); const int c3 = (0.0299 * 128 + 0.5);  const int half = (0.5000 * 128 + 0.5);  enum { q7_bits = 7 };  void firfixed(void) {     int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];     signed char output = (signed char)((sum + half) >> q7_bits);     put_q7(output); } 

on other hand, define fbits 16. require 32-bit integer types store (because you'd have 16 fractional bits , sign bit, 17 bits in total).

working code

#include <stdio.h>  const int c0 = (0.0299 * 128 + 0.5); const int c1 = (0.4701 * 128 + 0.5); const int c2 = (0.4701 * 128 + 0.5); const int c3 = (0.0299 * 128 + 0.5);  const int half = (0.5000 * 128 + 0.5);  enum { q7_bits = 7 };  void put_q7(signed char out); void firfixed(signed char input[4]);  void firfixed(signed char input[4]) {     int sum = c0*input[0] + c1*input[1] + c2*input[2] + c3*input[3];     signed char output = (signed char)((sum + half) >> q7_bits);     put_q7(output); }  void put_q7(signed char out) {     printf("out = %d\n", out); }  int main(void) {     printf("c0 = c3 = %3d = 0x%.2x\n", c0, c0);     printf("c1 = c2 = %3d = 0x%.2x\n", c1, c1);     signed char data[] = { 27, 39, 69, 99, 82, 71, 42, 63 };     (size_t = 0; < sizeof(data) - 4; i++)         firfixed(data + i);     return 0; } 

unvalidated output

i've not spent time calculating correct output. results shown plausible, that's as i'll claim.

c0 = c3 =   4 = 0x04 c1 = c2 =  60 = 0x3c out = 55 out = 83 out = 89 out = 76 

Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -