wavelib.c 30 KB

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