diff options
Diffstat (limited to 'md/writeup')
-rw-r--r-- | md/writeup/naive_fft_implementation_in_c.md | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/md/writeup/naive_fft_implementation_in_c.md b/md/writeup/naive_fft_implementation_in_c.md index e5729ee..d82cc57 100644 --- a/md/writeup/naive_fft_implementation_in_c.md +++ b/md/writeup/naive_fft_implementation_in_c.md @@ -16,6 +16,115 @@ MathJax = { <script type="text/javascript" id="MathJax-script" async src="/js/tex-chtml.js"> </script> +<script src="/demo/naive_fft/index.js"></script> + <script type='text/javascript'> + var Module = {}; + fetch('/demo/naive_fft/index.wasm') + .then(response => + response.arrayBuffer() + ).then(buffer => { + //Module.canvas = document.getElementById("canvas"); + Module.wasmBinary = buffer; + var script = document.createElement('script'); + script.src = "/demo/naive_fft/index.js"; + script.onload = function() { + console.log("Emscripten boilerplate loaded."); + run_dft = Module.cwrap("dft", [],[['float'],['float'],'number','number']); + run_fft_shuffle = Module.cwrap("ffti_shuffle_1", [],[['float'],['float'],'number']); + run_fft = Module.cwrap("fft_1", [],[['float'],['float'],'number','number']); + + + + var inputDataI = document.querySelector('.inputDataI'); + var inputDataIerr = document.querySelector('.inputDataIerr'); + var inputDataQ = document.querySelector('.inputDataQ'); + var inputDataQerr = document.querySelector('.inputDataQerr'); + var outputDataI = document.querySelector('.outputDataI'); + var outputDataQ = document.querySelector('.outputDataQ'); + + document.querySelector("#calcButton").onclick = function() { + console.log("calc FFT"); + + function cArray(size) { + var offset = Module._malloc(size * 8); + Module.HEAPF64.set(new Float64Array(size), offset / 8); + return { + "data": Module.HEAPF64.subarray(offset / 8, offset / 8 + size), + "offset": offset + } + } + + function checkArr(inputData,errorOutput) { + var strArr = inputData.value; + + strArr = strArr.replace(/ +(?= )/g,''); + var splArr = strArr.split(" "); + var data = Array(splArr.length).fill(0); + for (let i=0; i<splArr.length;i++) { + try { + var j=splArr[i]; + if ( j != parseFloat(j)) throw new Error("ERROR: not float "+splArr[i]+" at index "+i); + data[i] = parseFloat(j) + } catch (err) { + console.log("Error: ",err.message) + errorOutput.innerHTML = err.message; + return {"result":false,"data":[]}; + } + + } + return {"result":true,"data":data}; + } + console.log("checkArr"); + var arrIok = checkArr(inputDataI,inputDataIerr); + console.log("checkArr"); + var arrQok = checkArr(inputDataQ,inputDataQerr); + //max size 8 values, as thats enought for a demo + //https://stackoverflow.com/questions/17883799/how-to-handle-passing-returning-array-pointers-to-emscripten-compiled-code + if (!arrIok.result) return; + if (!arrQok.result) return; + + var N=8; + var myArray_i = cArray(N); + var myArray_q = cArray(N); + + //set test data + for(let i=0,j=0;i<N,j<arrIok.data.length;i++,j++) { + myArray_i.data[i] = arrIok.data[j]; + } + for(let i=0,j=0;i<N,j<arrQok.data.length;i++,j++) { + myArray_q.data[i] = arrQok.data[j]; + } + console.log(myArray_i.data); + console.log(myArray_q.data); + //DFT + run_dft(myArray_i.offset,myArray_q.offset,N,0); + //FFT + //run_fft_shuffle(myArray_i.offset,myArray_q.offset,N); + //run_fft(myArray_i.offset,myArray_q.offset,N,1); + + console.log(myArray_i.data); + console.log(myArray_q.data) + function outputResult(array,output) { + var arr = Array(array.slice(0,N)); + + arr = arr.map(function(item){ + return item.map(function(num){ + return parseFloat(num.toFixed(4)); + }); + }); + output.value = arr; + } + outputResult(myArray_i.data, outputDataI); + outputResult(myArray_q.data, outputDataQ); + + } + + } //end onload + document.body.appendChild(script); + }); + + + </script> Time to implement DFT/FFT by myself. Just followed Ifeachor book on theory part and IOWA FFT source on implementation side. @@ -212,6 +321,20 @@ res4 = fft(data4) ``` +### Demo + +Here hookedup demo of compiled wasm fft code location of demo source http://git.main.lv/cgit.cgi/NaiveFFT.git/tree/Build/index.html?h=main + +Two boxes for input and two boxes for output. Values set as vectors of complex numbers. First box for real +part, second box for imaginary part or in case of DSP IQ sample values. + +Input I:<textarea class="inputDataI">1 1 0</textarea><sup class="inputDataIerr"></sup> +Input Q:<textarea class="inputDataQ">0 0 0</textarea><sup class="inputDataQerr"></sup> +Output I:<textarea class="outputDataI"></textarea> +Output Q:<textarea class="outputDataQ"></textarea> +<button id="calcButton" type="button">Cals</button> + + ### Source Source located in main branch of git repo |