📄 std.c
字号:
/*************************************************************************** base_std.c - A std for the Base-directory ------------------- begin : 2003 authors : Linus Gasser emails : linus.gasser@epfl.ch ***************************************************************************//*************************************************************************** Changes ------- date - name - description 03/01/16 - ineiti - begin **************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//** * Description */#define DBG_LVL 0#include "system.h"#include "std.h"#include "debugging.h"#include <math.h>//----------------------------------------------------------------------// globals//----------------------------------------------------------------------#define POLYNOMIAL 0x04c11db7LU32 crc_table[256] ;//----------------------------------------------------------------------// Local functions//----------------------------------------------------------------------/* generate the table of CRC remainders for all possible bytes */void gen_crc_table( void ) { register int i, j ; register unsigned long crc_accum ; for ( i = 0; i < 256; i++ ) { crc_accum = ( (unsigned long) i << 24 ) ; for ( j = 0; j < 8; j++ ) { if ( crc_accum & 0x80000000L ) crc_accum = ( crc_accum << 1 ) ^ POLYNOMIAL ; else crc_accum = ( crc_accum << 1 ) ; } crc_table[i] = crc_accum ; } return ;}//----------------------------------------------------------------------// Exported functions//----------------------------------------------------------------------#ifdef KERNEL_SPACE#define DO_STACK#else#ifndef REDHAT_TLS#define DO_STACK#endif#endif/** * @short Initialises a thread */inline int swr_thread_init( struct thread *thr, void *func(void*), void *arg ) { pthread_attr_t attr;#ifdef DO_STACK thr->stack = swr_malloc( THREAD_STACK_SIZE ); if ( !thr->stack ) goto tc_no_stack;#endif pthread_attr_init( &attr );#ifdef DO_STACK pthread_attr_setstackaddr( &attr, thr->stack ); pthread_attr_setstacksize( &attr, THREAD_STACK_SIZE );#endif pthread_attr_setfp_np( &attr, 1 );#ifdef DO_STACK if ( pthread_create( &thr->thread, &attr, func, arg ) ) {#else if ( pthread_create( &thr->thread, NULL, func, arg ) ) {#endif pthread_attr_destroy( &attr );#ifdef DO_STACK swr_free( thr->stack );#endif return -1; } pthread_attr_destroy( &attr ); return 0;#ifdef DO_STACKtc_no_stack: return -2;#endif}/** * @short frees a thread */inline void swr_thread_free( struct thread *thr, void *arg ) { pthread_join( thr->thread, arg );#ifndef USER_SPACE // pthread_cancel( thr->thread );#endif#ifndef REDHAT_TLS swr_free( thr->stack );#endif}/** * @short calculates a crc32 */U32 swr_crc32( void *data, int len ) { register int i, j, crc_accum = 0x12345678; for ( j = 0; j < len; j++ ) { i = ( (int) ( crc_accum >> 24) ^ *((char*)data++) ) & 0xff ; crc_accum = ( crc_accum << 8 ) ^ crc_table[i] ; } return crc_accum ;}/** * @short calculates a crc32 in a struct */U32 swr_crc32_struct( void *data, int len ) { if ( len > sizeof( U32 ) ) { return swr_crc32( data + sizeof( U32 ), len - sizeof( U32 ) ); } else { return 0; }}/** * @short converts a double to a string */int swr_ftoa( char *str, double f, int pre, int post ) { double a, i; int d, e, post_pow; pre = max( pre, 1 ); pre = min( pre, 30 ); post = max( post, 0 ); post = min( post, 30 ); post_pow = pow( 10, post ); if ( f == 0 ) { sprintf( str, "0" ); a = 0, i = 0; } else { a = modf( log10( fabs( f ) ), &i ); if ( a > 0 ) { a -= 1.; i += 1.; } a += pre; i -= pre; a = pow( 10, a ); if ( f < 0 ) { a *= -1; } d = a; e = (int)i; if ( post == 0 ) { if ( e == 0 ) { sprintf( str, "%i", d ); } else { sprintf( str, "%ie%i", d, e ); } } else { post_pow = (int)fabs(a*post_pow)%post_pow; if ( e == 0 ) { sprintf( str, "%i.%0*i", d, post, abs(post_pow) ); } else { sprintf( str, "%i.%0*ie%i", d, post, abs(post_pow), e ); } } } return strlen( str );}/** * @short Converts a string to a double * * This should not be used externally to RTLinux-tasks, as the kernel doesn't * save the fp-registers on a task-switch. * * @param str the string to convert * @return double */#define str_ok(c) ((c=='-')||(c=='.')||(c=='e')||(c=='E')||((c>='0')&&(c<='9')))#define str_white(c) ((c==' ')||(c=='\t'))double swr_atof( char *str ) { double sign = 1., val = 0., val_pos = 1., val_mul = 10., val_mul_pos = 1., sig_exp = 1., exp = 0.; while ( str_white( *str ) ) { str++; } while ( str_ok( *str ) ) { if ( (*str == 'e') || (*str == 'E' ) ) { break; } if ( *str == '-' ) { sign = -1.; } else if ( *str == '.' ) { val_mul = 1.; val_mul_pos = .1; } else { val *= val_mul; val_pos *= val_mul_pos; val += (double)(*str - '0') * val_pos; } str++; } if ( ( *str == 'e' ) || ( *str == 'E' ) ) { str++; while ( str_ok( *str ) ) { if ( *str == '-' ) { sig_exp = -1.; } else { exp *= 10; exp += (double)(*str - '0'); str++; } } } return ( sign * val ) * pow( 10, sig_exp * exp );}void swr_fft(double *x,double *y,unsigned int order,int param){ unsigned int n,l,e,f,i,j,o,o1,j1,i1,k; double u,v,z,c,s,p,q,r,t,w,a; n=1u<<order; for(l=1;l<=order;l++) { u=1.0; v=0.0; e=1u<<(order-l+1); f=e/2; z=M_PI/f; c=cos(z); s=sin(z); if(param==SWR_FFT) s=-s; for(j=1;j<=f;j++) { for(i=j;i<=n;i+=e) { o=i+f-1; o1=i-1; p=x[o1]+x[o]; r=x[o1]-x[o]; q=y[o1]+y[o]; t=y[o1]-y[o]; x[o]=r*u-t*v; y[o]=t*u+r*v; x[o1]=p; y[o1]=q; } w=u*c-v*s; v=v*c+u*s; u=w; } } j=1; for(i=1;i<n;i++) { if(i<j) { j1=j-1; i1=i-1; p=x[j1]; q=y[j1]; x[j1]=x[i1]; y[j1]=y[i1]; x[i1]=p; y[i1]=q; } k=n/2; while(k<j) { j=j-k; k=k/2; } j+=k; } if(param==SWR_FFT) return; a=1.0/n; for(k=0;k<n;k++) { x[k]*=a; y[k]*=a; } return;}void swr_fft_complex(complex double *com,unsigned int order,int param){ unsigned int n,l,e,f,i,j,o,o1,j1,i1,k; double u,v,z,c,s,p,q,r,t,w,a; n=1u<<order; for(l=1;l<=order;l++) { u=1.0; v=0.0; e=1u<<(order-l+1); f=e/2; z=M_PI/f; c=cos(z); s=sin(z); if(param==SWR_FFT) s=-s; for(j=1;j<=f;j++) { for(i=j;i<=n;i+=e) { o=i+f-1; o1=i-1; p=creal(com[o1])+creal(com[o]); r=creal(com[o1])-creal(com[o]); q=cimag(com[o1])+cimag(com[o]); t=cimag(com[o1])-cimag(com[o]); com[o] = (r*u-t*v) + (t*u+r*v)*I; com[o1]= p + q*I; } w=u*c-v*s; v=v*c+u*s; u=w; } } j=1; for(i=1;i<n;i++) { if(i<j) { j1=j-1; i1=i-1; p=creal(com[j1]); q=cimag(com[j1]); com[j1] = com[i1]; com[i1] = p + q*I; } k=n/2; while(k<j) { j=j-k; k=k/2; } j+=k; } if(param==SWR_FFT) return; a=1.0/n; for(k=0;k<n;k++) { com[k] *= a; } return;}//----------------------------------------------------------------------// Module-specific functions//----------------------------------------------------------------------/** * This function is called when the module is loaded */int swr_std_init(void) { gen_crc_table(); return 0;}/** * This function is called when the module is unloaded. */void swr_std_cleanup(void) { PR_DBG( 2, "Std quit\n" );}/** * Kernel macros which define the initialization and finalization * function. */module_init(swr_std_init);module_exit(swr_std_cleanup);/** * The following symbols are exported: */EXPORT_SYMBOL(swr_crc32);EXPORT_SYMBOL(swr_crc32_struct);EXPORT_SYMBOL(swr_thread_init);EXPORT_SYMBOL(swr_thread_free);EXPORT_SYMBOL(swr_ftoa);EXPORT_SYMBOL(swr_atof);EXPORT_SYMBOL(swr_fft);EXPORT_SYMBOL(swr_fft_complex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -