wavelib.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. /*******************************************************************************
  2. 版权所有: 珠海欧力配网自动化股份有限公司
  3. 文件名称: wavelib.c
  4. 文件版本: 01.00
  5. 创建作者: ygl
  6. 创建日期: 2022-03-09
  7. 功能说明: modwt小波计算
  8. 其它说明: 支持:DB,sym、coif、haar
  9. 注意事项:只求近似值,不考虑数据重构
  10. */
  11. #ifdef __KERNEL__
  12. #include "head.h"
  13. #define M_SQRT2 1.41421356237309504880
  14. #else
  15. #include "head.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #define _USE_MATH_DEFINES
  20. #include <math.h>
  21. #include "wavelib.h"
  22. #define rt_malloc malloc
  23. // #define rt_printf printf
  24. #define rt_free free
  25. #endif
  26. hilbert_para coef1; //四组系数
  27. hilbert_para coef2;
  28. hilbert_para coef3;
  29. hilbert_para coef4;
  30. struct file *g_fpuo = NULL,*g_fpio = NULL;
  31. static const float db1[2] = {
  32. 7.071067811865475244008443621048490392848359376884740365883398e-01,
  33. 7.071067811865475244008443621048490392848359376884740365883398e-01
  34. };
  35. static const float db2[4] = {
  36. 4.829629131445341433748715998644486838169524195042022752011715e-01,
  37. 8.365163037378079055752937809168732034593703883484392934953414e-01,
  38. 2.241438680420133810259727622404003554678835181842717613871683e-01,
  39. -1.294095225512603811744494188120241641745344506599652569070016e-01
  40. };
  41. static const float db3[6] = {
  42. 3.326705529500826159985115891390056300129233992450683597084705e-01,
  43. 8.068915093110925764944936040887134905192973949948236181650920e-01,
  44. 4.598775021184915700951519421476167208081101774314923066433867e-01,
  45. -1.350110200102545886963899066993744805622198452237811919756862e-01,
  46. -8.544127388202666169281916918177331153619763898808662976351748e-02,
  47. 3.522629188570953660274066471551002932775838791743161039893406e-02
  48. };
  49. static const float db4[8] = {
  50. 2.303778133088965008632911830440708500016152482483092977910968e-01,
  51. 7.148465705529156470899219552739926037076084010993081758450110e-01,
  52. 6.308807679298589078817163383006152202032229226771951174057473e-01,
  53. -2.798376941685985421141374718007538541198732022449175284003358e-02,
  54. -1.870348117190930840795706727890814195845441743745800912057770e-01,
  55. 3.084138183556076362721936253495905017031482172003403341821219e-02,
  56. 3.288301166688519973540751354924438866454194113754971259727278e-02,
  57. -1.059740178506903210488320852402722918109996490637641983484974e-02
  58. };
  59. // static const float db5[10] = {
  60. // 1.601023979741929144807237480204207336505441246250578327725699e-01,
  61. // 6.038292697971896705401193065250621075074221631016986987969283e-01,
  62. // 7.243085284377729277280712441022186407687562182320073725767335e-01,
  63. // 1.384281459013207315053971463390246973141057911739561022694652e-01,
  64. // -2.422948870663820318625713794746163619914908080626185983913726e-01,
  65. // -3.224486958463837464847975506213492831356498416379847225434268e-02,
  66. // 7.757149384004571352313048938860181980623099452012527983210146e-02,
  67. // -6.241490212798274274190519112920192970763557165687607323417435e-03,
  68. // -1.258075199908199946850973993177579294920459162609785020169232e-02,
  69. // 3.335725285473771277998183415817355747636524742305315099706428e-03
  70. // };
  71. // All coif coefficents have to be multiplied by sqrt(2)
  72. static const float coif1[6] = {
  73. -5.142972847076845595317549230122688830344559947132656813651045e-02,
  74. 2.389297284707684559531754923012268883034455994713265681365104e-01,
  75. 6.028594569415369119063509846024537766068911989426531362730209e-01,
  76. 2.721405430584630880936490153975462233931088010573468637269790e-01,
  77. -5.142972847076845595317549230122688830344559947132656813651045e-02,
  78. -1.107027152923154404682450769877311169655440052867343186348954e-02
  79. };
  80. static const float coif2[12] = {
  81. 1.158759673871686817889714882853120395708315073355502818875931e-02,
  82. -2.932013798346856448679594524397843054053420947418409889774786e-02,
  83. -4.763959031100813225872995081511549408622753909592460525840745e-02,
  84. 2.730210465347666137982239328923516270034828327990699588033501e-01,
  85. 5.746823938568638472459483149751499367740786490481481391460366e-01,
  86. 2.948671936956191896750637208703777973914107635455611537640778e-01,
  87. -5.408560709171142997443672832006888537570221990444706777525838e-02,
  88. -4.202648046077160694657530752545884878978719268926222513485613e-02,
  89. 1.674441016327950635146257083249391698866289538037299820224006e-02,
  90. 3.967883612962012109043447090269950094081810916481648252817197e-03,
  91. -1.289203356140659543141355500990678257894936161704492503370186e-03,
  92. -5.095053991076441489598480835620951586540050976664367876412655e-04
  93. };
  94. static const float coif3[18] = {
  95. -2.682418670922068664584689955153722375535836177157637134187840e-03,
  96. 5.503126707831385107969640263617469178794666057252906037981936e-03,
  97. 1.658356047917034608134280439996549525220639437145367606178002e-02,
  98. -4.650776447872697640390293095170192691113917841041002855534619e-02,
  99. -4.322076356021191118175840907244577856782537221435748296465882e-02,
  100. 2.865033352736474630249006862976158896891076238443844211133873e-01,
  101. 5.612852568703300445990941995240077241406247774064453800050914e-01,
  102. 3.029835717728241602862575774374668529867757043461413348549577e-01,
  103. -5.077014075488886159516471867138370972545857441670871832472707e-02,
  104. -5.819625076158553022607041679522801089624825903982541419721721e-02,
  105. 2.443409432116695639462954438418928805487699080947974989338820e-02,
  106. 1.122924096203786563399489540091488781245346096838814728167341e-02,
  107. -6.369601011048822977293753932627342482077585617391852852955559e-03,
  108. -1.820458915566242322836631665832145136570132777862391313328351e-03,
  109. 7.902051009575939937150950543290226440287715441826917281929124e-04,
  110. 3.296651737931830308416338897758022998655744276957481989605186e-04,
  111. -5.019277455327664998007173088097694083956570594580641192332170e-05,
  112. -2.446573425530813115445387662881902303945941576472342106918209e-05
  113. };
  114. static const float coif4[24] = {
  115. 6.309612114309468490753696608619526520153127603444406835368201e-04,
  116. -1.152225143769973488683007937016166047881572156705066038094891e-03,
  117. -5.194525163470323267558201363327294331811309729430512113592118e-03,
  118. 1.136246148326482276463392678363118465908960082105224676102131e-02,
  119. 1.886723856956305960822813160712701905823879297781452350370094e-02,
  120. -5.746424190192718517290527411385172124443396690932404284859269e-02,
  121. -3.965265296244913762718094206756579981738035770770645437919302e-02,
  122. 2.936674050161006858761278962798582650835466243678172528509866e-01,
  123. 5.531264550395492870333469741987846570947502710783248169642137e-01,
  124. 3.071573096678856987248881030393884808414165269795297009902001e-01,
  125. -4.711273752389572084912399351781012121935994396763702238263689e-02,
  126. -6.803811467802056988332974920928626798429778679560269769187728e-02,
  127. 2.781363695846951303169163645831936314699164412528991864702607e-02,
  128. 1.773583142270308388403079552822372238681544967313003044695583e-02,
  129. -1.075631615508724933047071603601897536695959225169888787867102e-02,
  130. -4.001010844950535391911552472397083276670126595827549403173754e-03,
  131. 2.652664913530499860820143301690017184933302935238430721089152e-03,
  132. 8.955939276952843603555618778866181384528643960440369133096025e-04,
  133. -4.165001950941708741516836418852536615951250588002878691463468e-04,
  134. -1.838296167136253805617482342622910940008368723403836355183423e-04,
  135. 4.408022661597206973006038672236031501663774161685451815597956e-05,
  136. 2.208284691230832960893331999804142845136324572860276715790883e-05,
  137. -2.304919162676504406778986897925054839632903355820414483306851e-06,
  138. -1.262179179994622253884862172782890488140153502131112374520603e-06
  139. };
  140. // static const float coif5[30] = {
  141. // -1.499645228345950331670593167919531667975440598691604525531231e-04,
  142. // 2.535527523580334712936363872191554706055603482812691726895588e-04,
  143. // 1.540286725995222360335148244676269541414659303531250711822333e-03,
  144. // -2.941078164035693185044038586065593320891475311414770624555173e-03,
  145. // -7.164112349410053294382279572472252500899544810929605832362178e-03,
  146. // 1.655218330649288840540841623080651353621667424921282557975513e-02,
  147. // 1.991901719798432056056857854066125809443504706772520641876273e-02,
  148. // -6.499837825472324963374262221660858232544804226063450042795603e-02,
  149. // -3.680255347446873527191823500872992242220223547780834450868002e-02,
  150. // 2.980959014587191795511466861338063554509597132272839414668911e-01,
  151. // 5.475082713540367154128337935687830970431964302909253422329131e-01,
  152. // 3.097002590784203529311533316221254677074498876376965941549923e-01,
  153. // -4.386731482823615640442730013366750193381707273908757638050452e-02,
  154. // -7.464442013283971243472663968192859562973186442054433655531762e-02,
  155. // 2.919469277528073666095772398605275751022315529465178441510318e-02,
  156. // 2.310457227706684192610065243663928370022983285246219996141160e-02,
  157. // -1.397129268638200558584119246355879336305763752871371182932059e-02,
  158. // -6.476749751505861835547590642967453082384538848552165075614441e-03,
  159. // 4.781116799130657606400088024549264921093190305150784065791191e-03,
  160. // 1.719383484385504023022397097446276782318002683055773803854075e-03,
  161. // -1.174947934413537690027670037110105795928147523549002426409332e-03,
  162. // -4.508222400696236312231932151038336110220594834213702970043431e-04,
  163. // 2.134457975086291667348984871136041914777578046177470626552867e-04,
  164. // 9.924691139873533169989496559631669037970741600337089424730635e-05,
  165. // -2.914684388622130824599478843558087403539428940986384077972155e-05,
  166. // -1.504031798197685905639227292876711236513927746903476131955063e-05,
  167. // 2.616809660013118152124234488302931243021794024318439103773996e-06,
  168. // 1.457502921355163070577152619048168436286350537937563166257584e-06,
  169. // -1.148199649902979726237655584441763456854312591680755421569962e-07,
  170. // -6.791060677322355511541065559242475254516249773485524025251102e-08
  171. // };
  172. static const float sym2[4] = {
  173. 0.48296291314469025, 0.83651630373746899,
  174. 0.22414386804185735, -0.12940952255092145 };
  175. static const float sym3[6] = {
  176. 0.33267055295095688, 0.80689150931333875,
  177. 0.45987750211933132, -0.13501102001039084,
  178. -0.085441273882241486, 0.035226291882100656 };
  179. static const float sym4[8] = {
  180. 0.032223100604042702, -0.012603967262037833,
  181. -0.099219543576847216, 0.29785779560527736,
  182. 0.80373875180591614, 0.49761866763201545,
  183. -0.02963552764599851, -0.075765714789273325 };
  184. // static const float sym5[10] = {
  185. // 0.019538882735286728, -0.021101834024758855,
  186. // -0.17532808990845047, 0.016602105764522319,
  187. // 0.63397896345821192, 0.72340769040242059,
  188. // 0.1993975339773936, -0.039134249302383094,
  189. // 0.029519490925774643, 0.027333068345077982 };
  190. /* 要求:
  191. * (1)C0^2 + C1^2 + C2^2 + C3^2 = 1
  192. * (2)C1 * C3 + C0 * C2 = 0
  193. */
  194. /* 矩阵变换需要用到的参数 */
  195. static Filter DBn = {
  196. .Len = 4,
  197. .C0 = (const float) 0.482962913144690,
  198. .C1 = (const float) 0.836516303737469,
  199. .C2 = (const float) 0.224143868041857,
  200. .C3 = (const float) -0.129409522550921,
  201. };
  202. /* 按分解矩阵进行分解 */
  203. static void transform(float *input_Data, float *output_Data, int length)
  204. {
  205. int i=0;
  206. int count=0;
  207. for(i=0; i<=(length-3); i=i+1)
  208. {
  209. output_Data[count++] = DBn.C0 * input_Data[i] + DBn.C1 * input_Data[i+1] + DBn.C2 * input_Data[i+2] + DBn.C3 * input_Data[i+3];
  210. }
  211. output_Data[count++] = DBn.C2 * input_Data[0] + DBn.C3 * input_Data[1] + DBn.C0 * input_Data[length-2] + DBn.C1 * input_Data[length-1];
  212. output_Data[count] = DBn.C1 * input_Data[0] - DBn.C0 * input_Data[1] + DBn.C3 * input_Data[length-2] - DBn.C2 * input_Data[length-1];
  213. }
  214. /******************************************************************************
  215. * 功能:利用矩阵进行分解
  216. * @srcData: 源信号;
  217. * @resData: 保存结果;
  218. * @srcLen: 源信号长度;
  219. *******************************************************************************/
  220. void DWT_Matrix_Transform(float *srcData, s16 *resData, int srcLen)
  221. {
  222. int i=0;
  223. float out1Data[srcLen];
  224. memset(out1Data, 0, srcLen);
  225. transform(srcData, out1Data, srcLen);
  226. for (i = 0; i < srcLen; i +=1)
  227. {
  228. resData[i] = (s16)rt_round(out1Data[i]); //此处有风险,小心处理
  229. // *((s16 *)&resData[i]) = (s16)(out1Data[i]); //此处有风险,小心处理
  230. }
  231. return ;
  232. }
  233. /******************************************************************************
  234. 函数名称: hilbert_para_init
  235. 函数版本: 01.01
  236. 创建作者: ygl
  237. 创建日期: 2021.11.17
  238. 函数说明: hilbert初始化。
  239. 参数说明: 无
  240. 返回值: 长度
  241. 修改记录:
  242. *******************************************************************************/
  243. void _hilbert_para_init(void) //初始化系数
  244. {
  245. memset(&coef1, 0, sizeof(coef1));
  246. memset(&coef2, 0, sizeof(coef2));
  247. memset(&coef3, 0, sizeof(coef3));
  248. memset(&coef4, 0, sizeof(coef4));
  249. }
  250. /******************************************************************************
  251. 函数名称: filter_Init
  252. 函数版本: 01.01
  253. 创建作者: ygl
  254. 创建日期: 2021.11.17
  255. 函数说明: 卷积核初始化。
  256. 参数说明: 无
  257. 返回值: 长度
  258. 修改记录:
  259. *******************************************************************************/
  260. void filter_Init(void)
  261. {
  262. #if 0
  263. g_fpuo = rt_file_open("/app/uo.txt", O_CREAT|O_RDWR,0); //近似系数存储文件
  264. if(IS_ERR(g_fpuo))
  265. {
  266. rt_printf("LINE %d write file error!\n",__LINE__);
  267. rt_printf("write file error!\n");
  268. // return -1;
  269. }
  270. g_fpio = rt_file_open("/app/io.txt", O_CREAT|O_RDWR,0); //近似系数存储文件
  271. if(IS_ERR(g_fpio))
  272. {
  273. rt_printf("LINE %d write file error!\n",__LINE__);
  274. rt_printf("write file error!\n");
  275. // return -1;
  276. }
  277. #endif
  278. _hilbert_para_init();
  279. }
  280. float hilbert_filter(float *channel1, float *channel2, int len)
  281. {
  282. int i=0;
  283. const float c1=2.0216;
  284. const float c2=1.2562;
  285. const float c3=0.2276;
  286. const float c4=1.5219;
  287. const float c5=0.6205;
  288. const float c6=0.0463;
  289. // const float c1=2.1441;
  290. // const float c2=1.4380;
  291. // const float c3=0.2904;
  292. // const float c4=1.6444;
  293. // const float c5=0.7421;
  294. // const float c6=0.0658;
  295. float channel_f1 = 0;
  296. float channel_f2 = 0;
  297. float channel_f3 = 0;
  298. float channel_f4 = 0;
  299. float Qval = 0;
  300. memset(&coef1,0,sizeof(coef1));
  301. memset(&coef2,0,sizeof(coef2));
  302. memset(&coef3,0,sizeof(coef3));
  303. memset(&coef4,0,sizeof(coef4));
  304. for(i=0;i<len;i++)
  305. {
  306. channel_f1 = c1*(coef1.y2)-c2*(coef1.y4)+c3*(coef1.y6)+c3*(coef1.x1)-c2*(coef1.x3)+c1*(coef1.x5)-coef1.x7;
  307. coef1.y6 = coef1.y5;
  308. coef1.y5 = coef1.y4;
  309. coef1.y4 = coef1.y3;
  310. coef1.y3 = coef1.y2;
  311. coef1.y2 = coef1.y1;
  312. coef1.y1 = channel_f1;
  313. coef1.x7 = coef1.x6;
  314. coef1.x6 = coef1.x5;
  315. coef1.x5 = coef1.x4;
  316. coef1.x4 = coef1.x3;
  317. coef1.x3 = coef1.x2;
  318. coef1.x2 = coef1.x1;
  319. coef1.x1 = channel1[i];
  320. channel_f2 = c4*(coef2.y2)-c5*(coef2.y4)+c6*(coef2.y6)+c6*(channel1[i])-c5*(coef2.x2)+c4*(coef2.x4)-(coef2.x6);
  321. coef2.y6 = coef2.y5;
  322. coef2.y5 = coef2.y4;
  323. coef2.y4 = coef2.y3;
  324. coef2.y3 = coef2.y2;
  325. coef2.y2 = coef2.y1;
  326. coef2.y1 = channel_f2;
  327. coef2.x6 = coef2.x5;
  328. coef2.x5 = coef2.x4;
  329. coef2.x4 = coef2.x3;
  330. coef2.x3 = coef2.x2;
  331. coef2.x2 = coef2.x1;
  332. coef2.x1 = channel1[i];
  333. channel_f3 = c1*(coef3.y2)-c2*(coef3.y4)+c3*(coef3.y6)+c3*(coef3.x1)-c2*(coef3.x3)+c1*(coef3.x5)-coef3.x7;
  334. coef3.y6 = coef3.y5;
  335. coef3.y5 = coef3.y4;
  336. coef3.y4 = coef3.y3;
  337. coef3.y3 = coef3.y2;
  338. coef3.y2 = coef3.y1;
  339. coef3.y1 = channel_f3;
  340. coef3.x7 = coef3.x6;
  341. coef3.x6 = coef3.x5;
  342. coef3.x5 = coef3.x4;
  343. coef3.x4 = coef3.x3;
  344. coef3.x3 = coef3.x2;
  345. coef3.x2 = coef3.x1;
  346. coef3.x1 = channel2[i];
  347. channel_f4 = c4*(coef4.y2)-c5*(coef4.y4)+c6*(coef4.y6)+c6*(channel2[i])-c5*(coef4.x2)+c4*(coef4.x4)-(coef4.x6);
  348. coef4.y6 = coef4.y5;
  349. coef4.y5 = coef4.y4;
  350. coef4.y4 = coef4.y3;
  351. coef4.y3 = coef4.y2;
  352. coef4.y2 = coef4.y1;
  353. coef4.y1 = channel_f4;
  354. coef4.x6 = coef4.x5;
  355. coef4.x5 = coef4.x4;
  356. coef4.x4 = coef4.x3;
  357. coef4.x3 = coef4.x2;
  358. coef4.x2 = coef4.x1;
  359. coef4.x1 = channel2[i];
  360. Qval += (channel_f1*channel_f4 - channel_f2*channel_f3)/2;
  361. }
  362. Qval =(float) Qval/len;
  363. // rt_printf("len = %d,qval = %f\r\n",len,Qval);
  364. return Qval;
  365. }
  366. int filtlength(const char* name) {
  367. int len = strlen(name);
  368. int i = 0;
  369. char *new_str = NULL;
  370. int N = 0;
  371. if (!strcmp(name,"haar") || !strcmp(name,"db1")) {
  372. return 2;
  373. }
  374. else if (len > 2 && strstr(name, "db") != NULL)
  375. {
  376. new_str = (char*)rt_malloc(sizeof(char)*(len-2 + 1));
  377. for (i = 2; i < len + 1; i++)
  378. new_str[i - 2] = name[i];
  379. N = atoi(new_str);
  380. rt_free(new_str);
  381. if (N>38)
  382. {
  383. rt_printf("\n Filter Not in Database \n");
  384. return -1;
  385. }
  386. return N * 2;
  387. }
  388. else if (len > 4 && strstr(name, "coif") != NULL)
  389. {
  390. new_str = (char*)rt_malloc(sizeof(char)*(len - 4 + 1));
  391. for (i = 4; i < len + 1; i++)
  392. new_str[i - 4] = name[i];
  393. N = atoi(new_str);
  394. rt_free(new_str);
  395. if (N>17)
  396. {
  397. rt_printf("\n Filter Not in Database \n");
  398. return -1;
  399. }
  400. return N * 6;
  401. }
  402. else if (len > 3 && strstr(name, "sym") != NULL)
  403. {
  404. new_str = (char*)rt_malloc(sizeof(char)*(len - 3 + 1));
  405. for (i = 3; i < len + 1; i++)
  406. new_str[i - 3] = name[i];
  407. N = atoi(new_str);
  408. rt_free(new_str);
  409. if (N>20 || N < 2)
  410. {
  411. rt_printf("\n Filter Not in Database \n");
  412. return -1;
  413. }
  414. return N * 2;
  415. }
  416. else {
  417. rt_printf("\n Filter Not in Database \n");
  418. return -1;
  419. }
  420. }
  421. void copy_reverse(const float *in, int N,float *out)
  422. {
  423. int count = 0;
  424. for (count = 0; count < N; count++)
  425. out[count] = in[N - count - 1];
  426. }
  427. void qmf_even(const float *in, int N,float *out)
  428. {
  429. int count = 0;
  430. for (count = 0; count < N; count++)
  431. {
  432. out[count] = in[N - count - 1];
  433. if (count % 2 != 0)
  434. {
  435. out[count] = -1 * out[count];
  436. }
  437. }
  438. }
  439. void qmf_wrev(const float *in, int N, float *out)
  440. {
  441. float *sigOutTemp;
  442. sigOutTemp = (float*)rt_malloc(N*sizeof(float));
  443. qmf_even(in, N, sigOutTemp);
  444. copy_reverse(sigOutTemp, N, out);
  445. rt_free(sigOutTemp);
  446. return;
  447. }
  448. void wave_copy(const float *in, int N, float *out)
  449. {
  450. int count = 0;
  451. for (count = 0; count < N; count++)
  452. out[count] = in[count];
  453. }
  454. int filtcoef(const char* name, float *lp1, float *hp1, float *lp2, float *hp2) {
  455. int i = 0;
  456. int N = filtlength(name);
  457. if (!strcmp(name,"haar") || !strcmp(name,"db1")) {
  458. copy_reverse(db1, N, lp1);
  459. qmf_wrev(db1, N, hp1);
  460. wave_copy(db1, N, lp2);
  461. qmf_even(db1, N, hp2);
  462. return N;
  463. }
  464. else if (!strcmp(name,"db2")){
  465. copy_reverse(db2, N, lp1);
  466. qmf_wrev(db2, N, hp1);
  467. wave_copy(db2, N, lp2);
  468. qmf_even(db2, N, hp2);
  469. return N;
  470. }
  471. else if (!strcmp(name,"db3")){
  472. copy_reverse(db3, N, lp1);
  473. qmf_wrev(db3, N, hp1);
  474. wave_copy(db3, N, lp2);
  475. qmf_even(db3, N, hp2);
  476. return N;
  477. }
  478. else if (!strcmp(name,"db4")){
  479. copy_reverse(db4, N, lp1);
  480. qmf_wrev(db4, N, hp1);
  481. wave_copy(db4, N, lp2);
  482. qmf_even(db4, N, hp2);
  483. return N;
  484. }
  485. else if (!strcmp(name,"coif1")){
  486. float *coeffTemp;
  487. coeffTemp = (float*)rt_malloc(N*sizeof(float));
  488. wave_copy(coif1, N, coeffTemp);
  489. for (i = 0; i < N; ++i) {
  490. coeffTemp[i] *= M_SQRT2;
  491. }
  492. copy_reverse(coeffTemp, N, lp1);
  493. qmf_wrev(coeffTemp, N, hp1);
  494. wave_copy(coeffTemp, N, lp2);
  495. qmf_even(coeffTemp, N, hp2);
  496. rt_free(coeffTemp);
  497. return N;
  498. }
  499. else if (!strcmp(name,"coif2")){
  500. float *coeffTemp;
  501. coeffTemp = (float*)rt_malloc(N*sizeof(float));
  502. wave_copy(coif2, N, coeffTemp);
  503. for (i = 0; i < N; ++i) {
  504. coeffTemp[i] *= M_SQRT2;
  505. }
  506. copy_reverse(coeffTemp, N, lp1);
  507. qmf_wrev(coeffTemp, N, hp1);
  508. wave_copy(coeffTemp, N, lp2);
  509. qmf_even(coeffTemp, N, hp2);
  510. rt_free(coeffTemp);
  511. return N;
  512. }
  513. else if (!strcmp(name,"coif3")){
  514. float *coeffTemp;
  515. coeffTemp = (float*)rt_malloc(N*sizeof(float));
  516. wave_copy(coif3, N, coeffTemp);
  517. for (i = 0; i < N; ++i) {
  518. coeffTemp[i] *= M_SQRT2;
  519. }
  520. copy_reverse(coeffTemp, N, lp1);
  521. qmf_wrev(coeffTemp, N, hp1);
  522. wave_copy(coeffTemp, N, lp2);
  523. qmf_even(coeffTemp, N, hp2);
  524. rt_free(coeffTemp);
  525. return N;
  526. }
  527. else if (!strcmp(name,"coif4")){
  528. float *coeffTemp;
  529. coeffTemp = (float*)rt_malloc(N*sizeof(float));
  530. wave_copy(coif4, N, coeffTemp);
  531. for (i = 0; i < N; ++i) {
  532. coeffTemp[i] *= M_SQRT2;
  533. }
  534. copy_reverse(coeffTemp, N, lp1);
  535. qmf_wrev(coeffTemp, N, hp1);
  536. wave_copy(coeffTemp, N, lp2);
  537. qmf_even(coeffTemp, N, hp2);
  538. rt_free(coeffTemp);
  539. return N;
  540. }
  541. else if (!strcmp(name,"sym2") || !strcmp(name,"sym1")){
  542. copy_reverse(sym2, N, lp1);
  543. qmf_wrev(sym2, N, hp1);
  544. wave_copy(sym2, N, lp2);
  545. qmf_even(sym2, N, hp2);
  546. return N;
  547. }
  548. else if (!strcmp(name,"sym3")){
  549. copy_reverse(sym3, N, lp1);
  550. qmf_wrev(sym3, N, hp1);
  551. wave_copy(sym3, N, lp2);
  552. qmf_even(sym3, N, hp2);
  553. return N;
  554. }
  555. else if (!strcmp(name,"sym4")){
  556. copy_reverse(sym4, N, lp1);
  557. qmf_wrev(sym4, N, hp1);
  558. wave_copy(sym4, N, lp2);
  559. qmf_even(sym4, N, hp2);
  560. return N;
  561. }
  562. else {
  563. rt_printf("\n Filter Not in Database \n");
  564. return -1;
  565. }
  566. return 0;
  567. }
  568. wave_object wave_init(const char* wname) {
  569. wave_object obj = NULL;
  570. int retval;
  571. retval = 0;
  572. if (wname != NULL) {
  573. retval = filtlength(wname);
  574. }
  575. obj = (wave_object)rt_malloc(sizeof(struct wave_set) + sizeof(float)* 4 * retval);
  576. obj->filtlength = retval;
  577. obj->lpd_len = obj->hpd_len = obj->lpr_len = obj->hpr_len = obj->filtlength;
  578. strcpy(obj->wname, wname);
  579. if (wname != NULL) {
  580. filtcoef(wname,obj->params,obj->params+retval,obj->params+2*retval,obj->params+3*retval);
  581. }
  582. obj->lpd = &obj->params[0];
  583. obj->hpd = &obj->params[retval];
  584. obj->lpr = &obj->params[2 * retval];
  585. obj->hpr = &obj->params[3 * retval];
  586. return obj;
  587. }
  588. wt_object wt_init(wave_object wave,const char* method, int siglength,int J) {
  589. int i;
  590. wt_object obj = NULL;
  591. if (J > 100) {
  592. rt_printf("\n The Decomposition Iterations Cannot Exceed 100. Exiting \n");
  593. return NULL;
  594. }
  595. if (!strcmp(method, "modwt") || !strcmp(method, "MODWT")) {
  596. if (!strstr(wave->wname,"haar")) {
  597. if (!strstr(wave->wname,"db")) {
  598. if (!strstr(wave->wname, "sym")) {
  599. if (!strstr(wave->wname, "coif")) {
  600. rt_printf("\n MODWT is only implemented for orthogonal wavelet families - db, sym and coif \n");
  601. return NULL;
  602. }
  603. }
  604. }
  605. }
  606. // obj = (wt_object)rt_malloc(sizeof(struct wt_set) + sizeof(float)* (siglength * 2 * (J + 1)));
  607. // obj->outlength = siglength * (J + 1); // Default
  608. obj = (wt_object)rt_malloc(sizeof(struct wt_set) + sizeof(float)* (siglength * 2));
  609. obj->outlength = siglength ; //
  610. strcpy(obj->ext, "per"); // Default
  611. }
  612. obj->wave = wave;
  613. obj->siglength = siglength;
  614. obj->modwtsiglength = siglength;
  615. obj->J = J;
  616. // obj->MaxIter = MaxIter;
  617. strcpy(obj->method, method);
  618. if (siglength % 2 == 0) {
  619. obj->even = 1;
  620. }
  621. else {
  622. obj->even = 0;
  623. }
  624. obj->cobj = NULL;
  625. strcpy(obj->cmethod, "direct"); // Default
  626. obj->cfftset = 0;
  627. obj->lenlength = J + 2;
  628. obj->output = &obj->params[0];
  629. if (!strcmp(method, "modwt") || !strcmp(method, "MODWT")) {
  630. for (i = 0; i < siglength * 2; ++i) {
  631. obj->params[i] = 0.0;
  632. }
  633. }
  634. return obj;
  635. }
  636. static void modwt_per(wt_object wt, int M, float *inp, float *cA, int len_cA) {
  637. int l, i, t, len_avg;
  638. float s;
  639. float *filt;
  640. len_avg = wt->wave->lpd_len;
  641. filt = (float*)rt_malloc(sizeof(float)* len_avg);
  642. s = M_SQRT2;//sqrt(2.0);
  643. for (i = 0; i < len_avg; ++i) {
  644. filt[i] = wt->wave->lpd[i] / s;
  645. }
  646. for (i = 0; i < len_cA; ++i) {
  647. t = i;
  648. cA[i] = filt[0] * inp[t];
  649. for (l = 1; l < len_avg; l++) {
  650. t -= M;
  651. while (t >= len_cA) {
  652. t -= len_cA;
  653. }
  654. while (t < 0) {
  655. // t += len_cA; //ygl 传入波形数据,有可能首尾不对称。此处首核卷积改为第一点开始
  656. t += M;
  657. }
  658. cA[i] += filt[l] * inp[t];
  659. }
  660. }
  661. rt_free(filt);
  662. }
  663. static void modwt_direct(wt_object wt, const float *inp) {
  664. int i, J, temp_len, iter, M;
  665. float *cA;
  666. if (strcmp(wt->ext, "per")) {
  667. rt_printf("MODWT direct method only uses periodic extension per. \n");
  668. rt_printf(" Use MODWT fft method for symmetric extension sym \n");
  669. return;
  670. }
  671. temp_len = wt->siglength;
  672. J = wt->J;
  673. wt->length[0] = wt->length[J] = temp_len;
  674. wt->outlength = wt->length[J + 1] = temp_len; //只考虑近似值
  675. M = 1;
  676. for (iter = 1; iter < J; ++iter) {
  677. M = 2 * M;
  678. wt->length[iter] = temp_len;
  679. }
  680. cA = (float*)rt_malloc(sizeof(float)* temp_len);
  681. M = 1;
  682. for (i = 0; i < temp_len; ++i) {
  683. wt->params[i] = inp[i];
  684. }
  685. for (iter = 0; iter < J; ++iter) {
  686. if (iter > 0) {
  687. M = 2 * M;
  688. }
  689. modwt_per(wt, M, wt->params, cA, temp_len);
  690. for (i = 0; i < temp_len; ++i) {
  691. wt->params[i] = cA[i];
  692. }
  693. }
  694. rt_free(cA);
  695. }
  696. void modwt(wt_object wt, const float *inp) {
  697. if (!strcmp(wt->cmethod, "direct")) {
  698. modwt_direct(wt, inp);
  699. }
  700. else {
  701. rt_printf("Error- Available Choices for this method are - direct and fft \n");
  702. return;
  703. }
  704. }
  705. void wave_free(wave_object object) {
  706. rt_free(object);
  707. }
  708. void wt_free(wt_object object) {
  709. rt_free(object);
  710. }
  711. /*------------------------------ 内部函数 -------------------------------------
  712. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  713. */
  714. /*------------------------------ 测试函数 -------------------------------------
  715. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  716. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  717. */
  718. // #ifndef __KERNEL__
  719. #if 0
  720. /**************************************************************************
  721. 函数名称: main()
  722. 函数版本:1.00
  723. 作者: ygl
  724. 创建日期:2022.03.10
  725. 函数功能说明:小波测试函数,在vscode当前文件下测试。使用D:\\MinGW\\bin\\gcc.exe,需要配置vscode相关"launch.json"和"task.json“
  726. 支持:haar db1~5 sym2~5 coif1~5 共四类小波函数
  727. 输入参数:
  728. 输出参数:
  729. 返回值:
  730. ***************************************************************************/
  731. int main() {
  732. wave_object obj;
  733. wt_object wt;
  734. float *inp, *out, *diff;
  735. int N, i, J;
  736. FILE *ifp;
  737. FILE *fpAppCoef = NULL;
  738. float temp[10000];
  739. char *name = "haar";
  740. obj = wave_init(name);
  741. // wave_summary(obj);
  742. // ifp = fopen("signal.txt", "r");
  743. ifp = fopen("myDWTData4.txt", "r");
  744. fseek(ifp,0,SEEK_END);
  745. N = ftell(ifp)/7;
  746. fseek(ifp,0,SEEK_SET);
  747. i = 0;
  748. if (!ifp) {
  749. printf("Cannot Open File");
  750. exit(100);
  751. }
  752. while (!feof(ifp)) {
  753. fscanf(ifp, "%f \n", &temp[i]);
  754. i++;
  755. }
  756. //***********************************把注释取消掉,可以将变换结果存于文件****************************************
  757. if(NULL == (fpAppCoef = fopen("DWT_AppData.txt", "w"))) //近似系数存储文件
  758. {
  759. printf("write file error!\n");
  760. return -1;
  761. }
  762. //***********************************************************************************************************/
  763. // N = 177;
  764. fclose(ifp);
  765. inp = (float*)malloc(sizeof(float)* N);
  766. out = (float*)malloc(sizeof(float)* N);
  767. diff = (float*)malloc(sizeof(float)* N);
  768. //wmean = mean(temp, N);
  769. for (i = 0; i < N; ++i) {
  770. inp[i] = temp[i];
  771. //printf("%g \n",inp[i]);
  772. }
  773. J = 4;
  774. wt = wt_init(obj, "modwt", N, J);// Initialize the wavelet transform object
  775. modwt(wt, inp);// Perform MODWT
  776. //MODWT output can be accessed using wt->output vector. Use wt_summary to find out how to extract appx and detail coefficients
  777. for (i = 0; i < wt->outlength; ++i) {
  778. printf("%g ",wt->output[i]);
  779. fprintf(fpAppCoef, "%f\t", wt->output[i]); //将数据流写入文件
  780. }
  781. // imodwt(wt, out);// Perform ISWT (if needed)
  782. // Test Reconstruction
  783. // for (i = 0; i < wt->siglength; ++i) {
  784. // diff[i] = out[i] - inp[i];
  785. // }
  786. fclose(fpAppCoef);
  787. wave_free(obj);
  788. wt_free(wt);
  789. rt_free(inp);
  790. rt_free(out);
  791. rt_free(diff);
  792. return 0;
  793. }
  794. #endif
  795. /*------------------------------ 文件结束 -------------------------------------
  796. */