{"id":1213,"date":"2020-04-13T11:33:47","date_gmt":"2020-04-13T09:33:47","guid":{"rendered":"https:\/\/innovatiestudio.hku.nl\/?p=1213"},"modified":"2020-04-13T11:48:10","modified_gmt":"2020-04-13T09:48:10","slug":"diy-inverse-fast-fourier-transform-ifft","status":"publish","type":"post","link":"https:\/\/innovatiestudio.hku.nl\/?p=1213","title":{"rendered":"DIY Inverse Fast Fourier Transform (IFFT)"},"content":{"rendered":"\n<p>For a previous project a generative music system was implemented in Unity featuring rich sounding ensemble strings based on PADSynth. PADsynth is an algorithm designed by Nasca Octavian Paul that generates complex wavetables by varying the width of harmonics in the frequency spectrum, and using the Inverse Fast Fourier Transform (IFFT) to convert it to a time domain audio signal.  <\/p>\n\n\n\n<p>The general idea behind the PADSynth algorithm is that complex sounding ensembles are the result of randomized phases and Gaussian distributions in harmonic content. If this sounds a bit abstract you could think of it as this: in an acoustic string ensemble all instruments ever so slightly out-of-tune because of small variations in instrument materials, dimensions, tuning, age, et cetera. There variations become more pronounced in higher frequency content. By widening the bandwidth of higher frequency harmonic content one can create airy pads or choir wavetables.  <\/p>\n\n\n\n<p>Below are two clips recorded from the PADSynth implementation in Unity.<\/p>\n\n\n\n<figure class=\"wp-block-audio\"><audio controls src=\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/clip1.wav\"><\/audio><\/figure>\n\n\n\n<figure class=\"wp-block-audio\"><audio controls src=\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/clip2.wav\"><\/audio><\/figure>\n\n\n\n<p>The need for an Inverse Fast Fourier Transform (IFFT) comes into play when converting frequency domain content to time domain content. Unity affords an FFT operation which converts time domain audio to a frequency domain spectrum data on an AudioSource through the method GetSpectrumData, however it doesn&#8217;t afford a method that does the inverse: convert spectrum data back to a time domain audio signal. <\/p>\n\n\n\n<p>There are some very powerful FFT libraries available such as <em><a href=\"http:\/\/www.fftw.org\/\">FFTW <\/a><\/em>(Frigo &amp; Johnson 2003) that afford performance optimized IFFT, however they&#8217;re a bit of a hassle to use with a Unity project unless you&#8217;re using a C# wrapper such as Szalay&#8217;s <a href=\"https:\/\/github.com\/tszalay\/FFTWSharp\"><em>FFTWSharp<\/em> <\/a>(2015). For the purpose of getting intimately familiar with FFT\/IFFT and in the spirit of Open Science the choice was made to write a custom C# script. <\/p>\n\n\n\n<p><strong>Inverse Fast Fourier Transform<\/strong><\/p>\n\n\n\n<p>After spending a weekend looking into FFT it turned out IFFT wasn&#8217;t nearly as complicated as expected. In fact it&#8217;s possible to compute an Inverse FFT <a href=\"https:\/\/www.dsprelated.com\/showarticle\/800.php\">by using the Forward FFT algorithm by way of complex conjugation<\/a>.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"282\" src=\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-1024x282.jpg\" alt=\"\" class=\"wp-image-1214\" srcset=\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-1024x282.jpg 1024w, https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-300x83.jpg 300w, https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-768x211.jpg 768w, https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-500x138.jpg 500w, https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-800x220.jpg 800w, https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg 1097w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This results in a real-valued time signal so the imaginary part can be discarded, hence in the C# implementation below there&#8217;s no second inversion of the imaginary part and only the real part is normalized and returned.<\/p>\n\n\n\n<p>Below you can find the IFFT algorithm implementation used for the PADSynth test in Unity, arrays <em>real <\/em>and <em>imag <\/em>are assumed to have the exact same length. <\/p>\n\n\n\n<pre style=\"color:#000000;background:#ffffff;\">public <span style=\"color:#800000; font-weight:bold; \">float<\/span><span style=\"color:#808030; \">[<\/span><span style=\"color:#808030; \">]<\/span> GetSamplesFromSpectrum<span style=\"color:#808030; \">(<\/span><span style=\"color:#800000; font-weight:bold; \">float<\/span><span style=\"color:#808030; \">[<\/span><span style=\"color:#808030; \">]<\/span> real<span style=\"color:#808030; \">,<\/span> <span style=\"color:#800000; font-weight:bold; \">float<\/span><span style=\"color:#808030; \">[<\/span><span style=\"color:#808030; \">]<\/span> imag<span style=\"color:#808030; \">)<\/span>\n<span style=\"color:#800080; \">{<\/span>\n\tuint windowSize <span style=\"color:#808030; \">=<\/span> <span style=\"color:#808030; \">(<\/span>uint<span style=\"color:#808030; \">)<\/span>real<span style=\"color:#808030; \">.<\/span>Length<span style=\"color:#800080; \">;<\/span>\n\tuint n <span style=\"color:#808030; \">=<\/span> windowSize<span style=\"color:#800080; \">;<\/span>\n\tuint j <span style=\"color:#808030; \">=<\/span> n <span style=\"color:#808030; \">\/<\/span> <span style=\"color:#008c00; \">2<\/span><span style=\"color:#800080; \">;<\/span>\n\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> temp<span style=\"color:#800080; \">;<\/span>\t\n\t\t\t\t\t\n\t<span style=\"color:#800000; font-weight:bold; \">for<\/span> <span style=\"color:#808030; \">(<\/span>uint i <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">1<\/span><span style=\"color:#800080; \">;<\/span> i <span style=\"color:#808030; \">&lt;<\/span> windowSize <span style=\"color:#808030; \">-<\/span> <span style=\"color:#008c00; \">2<\/span><span style=\"color:#800080; \">;<\/span> i<span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">)<\/span> \n\t<span style=\"color:#800080; \">{<\/span>\n\t\timag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> <span style=\"color:#808030; \">-<\/span>imag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\n\t\t<span style=\"color:#800000; font-weight:bold; \">if<\/span> <span style=\"color:#808030; \">(<\/span>i <span style=\"color:#808030; \">&lt;<\/span> j<span style=\"color:#808030; \">)<\/span>\n\t\t<span style=\"color:#800080; \">{<\/span>\n\t\t\ttemp <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>j<span style=\"color:#808030; \">]<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\treal<span style=\"color:#808030; \">[<\/span>j<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\treal<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> temp<span style=\"color:#800080; \">;<\/span>\n\t\t\t\n\t\t\ttemp <span style=\"color:#808030; \">=<\/span> imag<span style=\"color:#808030; \">[<\/span>j<span style=\"color:#808030; \">]<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\timag<span style=\"color:#808030; \">[<\/span>j<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> imag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\timag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> temp<span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800080; \">}<\/span>\n\n\t\tuint k <span style=\"color:#808030; \">=<\/span> windowSize <span style=\"color:#808030; \">&gt;<\/span><span style=\"color:#808030; \">&gt;<\/span> <span style=\"color:#008c00; \">1<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800000; font-weight:bold; \">while<\/span> <span style=\"color:#808030; \">(<\/span>k <span style=\"color:#808030; \">&lt;<\/span><span style=\"color:#808030; \">=<\/span> j<span style=\"color:#808030; \">)<\/span>\n\t\t<span style=\"color:#800080; \">{<\/span>\n\t\t\tj <span style=\"color:#808030; \">-<\/span><span style=\"color:#808030; \">=<\/span> k<span style=\"color:#800080; \">;<\/span>\n\t\t\tk <span style=\"color:#808030; \">&gt;<\/span><span style=\"color:#808030; \">&gt;<\/span><span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">1<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800080; \">}<\/span>\n\t\tj <span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">=<\/span> k<span style=\"color:#800080; \">;<\/span>\n\t<span style=\"color:#800080; \">}<\/span>\n\t\t\n\tuint windowEnd <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">1<\/span><span style=\"color:#800080; \">;<\/span>\n\t\n\tuint bitCount <span style=\"color:#808030; \">=<\/span> <span style=\"color:#808030; \">(<\/span>uint<span style=\"color:#808030; \">)<\/span>Mathf<span style=\"color:#808030; \">.<\/span>Log<span style=\"color:#808030; \">(<\/span>windowSize<span style=\"color:#808030; \">,<\/span> <span style=\"color:#008c00; \">2<\/span><span style=\"color:#808030; \">)<\/span><span style=\"color:#800080; \">;<\/span>\n\t<span style=\"color:#800000; font-weight:bold; \">for<\/span> <span style=\"color:#808030; \">(<\/span>uint lp <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">0<\/span><span style=\"color:#800080; \">;<\/span> lp <span style=\"color:#808030; \">&lt;<\/span> bitCount<span style=\"color:#800080; \">;<\/span> lp<span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">)<\/span>\n\t<span style=\"color:#800080; \">{<\/span>\n\t\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> re <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008000; \">1.0<\/span><span style=\"color:#006600; \">f<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> im <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008000; \">0.0<\/span><span style=\"color:#006600; \">f<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t\n\t\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> c <span style=\"color:#808030; \">=<\/span>  Mathf<span style=\"color:#808030; \">.<\/span>Cos<span style=\"color:#808030; \">(<\/span>Mathf<span style=\"color:#808030; \">.<\/span>PI <span style=\"color:#808030; \">\/<\/span> windowEnd<span style=\"color:#808030; \">)<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> s <span style=\"color:#808030; \">=<\/span> <span style=\"color:#808030; \">-<\/span>Mathf<span style=\"color:#808030; \">.<\/span>Sin<span style=\"color:#808030; \">(<\/span>Mathf<span style=\"color:#808030; \">.<\/span>PI <span style=\"color:#808030; \">\/<\/span> windowEnd<span style=\"color:#808030; \">)<\/span><span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800000; font-weight:bold; \">float<\/span> tsr<span style=\"color:#808030; \">,<\/span> tsi<span style=\"color:#800080; \">;<\/span>\n\n\t\t<span style=\"color:#800000; font-weight:bold; \">for<\/span> <span style=\"color:#808030; \">(<\/span>j <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">0<\/span><span style=\"color:#800080; \">;<\/span> j <span style=\"color:#808030; \">&lt;<\/span> windowEnd<span style=\"color:#800080; \">;<\/span> j<span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">)<\/span>\n\t\t<span style=\"color:#800080; \">{<\/span>\n\t\t\t<span style=\"color:#800000; font-weight:bold; \">for<\/span> <span style=\"color:#808030; \">(<\/span>uint i <span style=\"color:#808030; \">=<\/span> j<span style=\"color:#800080; \">;<\/span> i <span style=\"color:#808030; \">&lt;<\/span> n<span style=\"color:#800080; \">;<\/span> i <span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">=<\/span> windowEnd <span style=\"color:#808030; \">*<\/span> <span style=\"color:#008c00; \">2<\/span><span style=\"color:#808030; \">)<\/span>\n\t\t\t<span style=\"color:#800080; \">{<\/span>\n\t\t\t\tuint k <span style=\"color:#808030; \">=<\/span> i <span style=\"color:#808030; \">+<\/span> windowEnd<span style=\"color:#800080; \">;<\/span>\n\t\t\t\t\n\t\t\t\ttsr <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">*<\/span> re <span style=\"color:#808030; \">-<\/span> imag<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">*<\/span> im<span style=\"color:#800080; \">;<\/span>\n\t\t\t\ttsi <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">*<\/span> im <span style=\"color:#808030; \">+<\/span> imag<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">*<\/span> re<span style=\"color:#800080; \">;<\/span>\n\t\t\t\t\n\t\t\t\treal<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">-<\/span> tsr<span style=\"color:#800080; \">;<\/span>\n\t\t\t\timag<span style=\"color:#808030; \">[<\/span>k<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> imag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">-<\/span> tsi<span style=\"color:#800080; \">;<\/span>\n\t\t\t\treal<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">+<\/span> tsr<span style=\"color:#800080; \">;<\/span>\n\t\t\t\timag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> imag<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">+<\/span> tsi<span style=\"color:#800080; \">;<\/span>\n\t\t\t<span style=\"color:#800080; \">}<\/span>\t\n\t\t\t\n\t\t\ttsr <span style=\"color:#808030; \">=<\/span> re<span style=\"color:#800080; \">;<\/span>\n\t\t\tre <span style=\"color:#808030; \">=<\/span> tsr <span style=\"color:#808030; \">*<\/span> c <span style=\"color:#808030; \">-<\/span> im <span style=\"color:#808030; \">*<\/span> s<span style=\"color:#800080; \">;<\/span>\n\t\t\tim <span style=\"color:#808030; \">=<\/span> tsr <span style=\"color:#808030; \">*<\/span> s <span style=\"color:#808030; \">+<\/span> im <span style=\"color:#808030; \">*<\/span> c<span style=\"color:#800080; \">;<\/span>\n\t\t<span style=\"color:#800080; \">}<\/span>\n\t\t\n\t\twindowEnd <span style=\"color:#808030; \">&lt;<\/span><span style=\"color:#808030; \">&lt;<\/span><span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">1<\/span><span style=\"color:#800080; \">;<\/span>\n\t<span style=\"color:#800080; \">}<\/span>\n\n\t<span style=\"color:#800000; font-weight:bold; \">for<\/span> <span style=\"color:#808030; \">(<\/span>uint i <span style=\"color:#808030; \">=<\/span> <span style=\"color:#008c00; \">0<\/span><span style=\"color:#800080; \">;<\/span> i <span style=\"color:#808030; \">&lt;<\/span> n<span style=\"color:#800080; \">;<\/span> i<span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">+<\/span><span style=\"color:#808030; \">)<\/span>\n\t<span style=\"color:#800080; \">{<\/span>\n\t\treal<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">=<\/span> real<span style=\"color:#808030; \">[<\/span>i<span style=\"color:#808030; \">]<\/span> <span style=\"color:#808030; \">\/<\/span> n<span style=\"color:#800080; \">;<\/span>\n\t<span style=\"color:#800080; \">}<\/span>\n\n\t<span style=\"color:#800000; font-weight:bold; \">return<\/span> real<span style=\"color:#800080; \">;<\/span>\n<span style=\"color:#800080; \">}<\/span>\t\t\n<\/pre>\n<!--Created using ToHtml.com on 2019-10-08 15:36:33 UTC -->\n\n\n\n<p>The code wasn&#8217;t thoroughly tested but it produced the intended results for the PADSynth implementation. It&#8217;s made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication. <a href=\"https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/\">https:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/<\/a>.<\/p>\n\n\n\n<p><strong>References<\/strong><br>Frigo, M., Johnson, S. (2003). <em>FFTW. <\/em>Massachusetts Institute of Technology. [Available <a href=\"http:\/\/citeseerx.ist.psu.edu\/viewdoc\/download;jsessionid=F60D7C013598BAACD7800763769472A3?doi=10.1.1.207.1436&amp;rep=rep1&amp;type=pdf\">h<\/a><a href=\"http:\/\/www.fftw.org\/\">e<\/a><a href=\"http:\/\/citeseerx.ist.psu.edu\/viewdoc\/download;jsessionid=F60D7C013598BAACD7800763769472A3?doi=10.1.1.207.1436&amp;rep=rep1&amp;type=pdf\">re<\/a>]<br><br>Lyons, R. (2015). <em>Four Ways to Compute an Inverse FFT Using the Forward FFT Algorithm<\/em>. DSP Related. [Available <a href=\"https:\/\/www.dsprelated.com\/showarticle\/800.php\">here<\/a>]<br><br>Nasca, P. (2011). <em>Padsynth Sound Synthesis Algorithm.<\/em> Studia Universitatis Babes-Bolyai, Informatica  [Available <a href=\"http:\/\/zynaddsubfx.sourceforge.net\/doc\/PADsynth\/PADsynth.htm\">here<\/a>]<br><br>Szalay, T. (2015). <em>FFTWSharp<\/em>. GitHub. [Available <a href=\"https:\/\/github.com\/tszalay\/FFTWSharp\">here<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For a previous project a generative music system was implemented in Unity featuring rich sounding ensemble strings based on PADSynth. PADsynth is an algorithm designed by Nasca Octavian Paul that generates complex wavetables by varying the width of harmonics in the frequency spectrum, and using the Inverse Fast Fourier Transform (IFFT) to convert it to [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":1214,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"tteo2020_transparent_header":false,"footnotes":""},"categories":[10,26],"tags":[],"class_list":["post-1213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-research-items","category-snippetsinspiration"],"featured_image_urls_v2":{"full":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"thumbnail":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-150x150.jpg",150,150,true],"medium":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-300x83.jpg",300,83,true],"medium_large":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-768x211.jpg",580,159,true],"large":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-1024x282.jpg",580,160,true],"1536x1536":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"2048x2048":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"post-thumbnail":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"twentytwenty-fullscreen":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"awb_sm":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-500x138.jpg",500,138,true],"awb_md":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite-800x220.jpg",800,220,true],"awb_lg":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false],"awb_xl":["https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg",1097,302,false]},"post_excerpt_stackable_v2":"<p>For a previous project a generative music system was implemented in Unity featuring rich sounding ensemble strings based on PADSynth. PADsynth is an algorithm designed by Nasca Octavian Paul that generates complex wavetables by varying the width of harmonics in the frequency spectrum, and using the Inverse Fast Fourier Transform (IFFT) to convert it to a time domain audio signal. The general idea behind the PADSynth algorithm is that complex sounding ensembles are the result of randomized phases and Gaussian distributions in harmonic content. If this sounds a bit abstract you could think of it as this: in an acoustic&hellip;<\/p>\n","category_list_v2":"<a href=\"https:\/\/innovatiestudio.hku.nl\/?cat=10\" rel=\"category\">R&amp;D<\/a>, <a href=\"https:\/\/innovatiestudio.hku.nl\/?cat=26\" rel=\"category\">Snippets and Inspiration<\/a>","author_info_v2":{"name":"Niels Keetels","url":"https:\/\/innovatiestudio.hku.nl\/?author=3"},"comments_num_v2":"0 comments","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/innovatiestudio.hku.nl\/?p=1213\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio\" \/>\n<meta property=\"og:description\" content=\"For a previous project a generative music system was implemented in Unity featuring rich sounding ensemble strings based on PADSynth. PADsynth is an algorithm designed by Nasca Octavian Paul that generates complex wavetables by varying the width of harmonics in the frequency spectrum, and using the Inverse Fast Fourier Transform (IFFT) to convert it to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/innovatiestudio.hku.nl\/?p=1213\" \/>\n<meta property=\"og:site_name\" content=\"HKU Innovation Studio\" \/>\n<meta property=\"article:published_time\" content=\"2020-04-13T09:33:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-04-13T09:48:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1097\" \/>\n\t<meta property=\"og:image:height\" content=\"302\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Niels Keetels\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Niels Keetels\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#article\",\"isPartOf\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213\"},\"author\":{\"name\":\"Niels Keetels\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/b6c5c25acbd8e2c1f153864baf08d452\"},\"headline\":\"DIY Inverse Fast Fourier Transform (IFFT)\",\"datePublished\":\"2020-04-13T09:33:47+00:00\",\"dateModified\":\"2020-04-13T09:48:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213\"},\"wordCount\":483,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#organization\"},\"image\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage\"},\"thumbnailUrl\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg\",\"articleSection\":[\"R&amp;D\",\"Snippets and Inspiration\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/innovatiestudio.hku.nl\/?p=1213#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213\",\"url\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213\",\"name\":\"DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio\",\"isPartOf\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage\"},\"image\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage\"},\"thumbnailUrl\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg\",\"datePublished\":\"2020-04-13T09:33:47+00:00\",\"dateModified\":\"2020-04-13T09:48:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/innovatiestudio.hku.nl\/?p=1213\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage\",\"url\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg\",\"contentUrl\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg\",\"width\":1097,\"height\":302},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/?p=1213#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/innovatiestudio.hku.nl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DIY Inverse Fast Fourier Transform (IFFT)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#website\",\"url\":\"https:\/\/innovatiestudio.hku.nl\/\",\"name\":\"HKU Innovation Studio\",\"description\":\"HKU Innovation Studio project page\",\"publisher\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/innovatiestudio.hku.nl\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#organization\",\"name\":\"HKU Innovation Studio\",\"url\":\"https:\/\/innovatiestudio.hku.nl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/cropped-botbrawl-1.jpg\",\"contentUrl\":\"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/cropped-botbrawl-1.jpg\",\"width\":468,\"height\":333,\"caption\":\"HKU Innovation Studio\"},\"image\":{\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/b6c5c25acbd8e2c1f153864baf08d452\",\"name\":\"Niels Keetels\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5988d9ac2d854760a39f31008af3ccb5e8fc3da7835241ecdffd06b87a88d0c6?s=96&d=retro&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5988d9ac2d854760a39f31008af3ccb5e8fc3da7835241ecdffd06b87a88d0c6?s=96&d=retro&r=g\",\"caption\":\"Niels Keetels\"},\"url\":\"https:\/\/innovatiestudio.hku.nl\/?author=3\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/innovatiestudio.hku.nl\/?p=1213","og_locale":"en_US","og_type":"article","og_title":"DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio","og_description":"For a previous project a generative music system was implemented in Unity featuring rich sounding ensemble strings based on PADSynth. PADsynth is an algorithm designed by Nasca Octavian Paul that generates complex wavetables by varying the width of harmonics in the frequency spectrum, and using the Inverse Fast Fourier Transform (IFFT) to convert it to [&hellip;]","og_url":"https:\/\/innovatiestudio.hku.nl\/?p=1213","og_site_name":"HKU Innovation Studio","article_published_time":"2020-04-13T09:33:47+00:00","article_modified_time":"2020-04-13T09:48:10+00:00","og_image":[{"width":1097,"height":302,"url":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg","type":"image\/jpeg"}],"author":"Niels Keetels","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Niels Keetels","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#article","isPartOf":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213"},"author":{"name":"Niels Keetels","@id":"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/b6c5c25acbd8e2c1f153864baf08d452"},"headline":"DIY Inverse Fast Fourier Transform (IFFT)","datePublished":"2020-04-13T09:33:47+00:00","dateModified":"2020-04-13T09:48:10+00:00","mainEntityOfPage":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213"},"wordCount":483,"commentCount":0,"publisher":{"@id":"https:\/\/innovatiestudio.hku.nl\/#organization"},"image":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage"},"thumbnailUrl":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg","articleSection":["R&amp;D","Snippets and Inspiration"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/innovatiestudio.hku.nl\/?p=1213#respond"]}]},{"@type":"WebPage","@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213","url":"https:\/\/innovatiestudio.hku.nl\/?p=1213","name":"DIY Inverse Fast Fourier Transform (IFFT) &#187; HKU Innovation Studio","isPartOf":{"@id":"https:\/\/innovatiestudio.hku.nl\/#website"},"primaryImageOfPage":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage"},"image":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage"},"thumbnailUrl":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg","datePublished":"2020-04-13T09:33:47+00:00","dateModified":"2020-04-13T09:48:10+00:00","breadcrumb":{"@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/innovatiestudio.hku.nl\/?p=1213"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#primaryimage","url":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg","contentUrl":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/ifftwebsite.jpg","width":1097,"height":302},{"@type":"BreadcrumbList","@id":"https:\/\/innovatiestudio.hku.nl\/?p=1213#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/innovatiestudio.hku.nl\/"},{"@type":"ListItem","position":2,"name":"DIY Inverse Fast Fourier Transform (IFFT)"}]},{"@type":"WebSite","@id":"https:\/\/innovatiestudio.hku.nl\/#website","url":"https:\/\/innovatiestudio.hku.nl\/","name":"HKU Innovation Studio","description":"HKU Innovation Studio project page","publisher":{"@id":"https:\/\/innovatiestudio.hku.nl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/innovatiestudio.hku.nl\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/innovatiestudio.hku.nl\/#organization","name":"HKU Innovation Studio","url":"https:\/\/innovatiestudio.hku.nl\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/innovatiestudio.hku.nl\/#\/schema\/logo\/image\/","url":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/cropped-botbrawl-1.jpg","contentUrl":"https:\/\/innovatiestudio.hku.nl\/wp-content\/uploads\/2020\/04\/cropped-botbrawl-1.jpg","width":468,"height":333,"caption":"HKU Innovation Studio"},"image":{"@id":"https:\/\/innovatiestudio.hku.nl\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/b6c5c25acbd8e2c1f153864baf08d452","name":"Niels Keetels","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/innovatiestudio.hku.nl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5988d9ac2d854760a39f31008af3ccb5e8fc3da7835241ecdffd06b87a88d0c6?s=96&d=retro&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5988d9ac2d854760a39f31008af3ccb5e8fc3da7835241ecdffd06b87a88d0c6?s=96&d=retro&r=g","caption":"Niels Keetels"},"url":"https:\/\/innovatiestudio.hku.nl\/?author=3"}]}},"_links":{"self":[{"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/posts\/1213","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1213"}],"version-history":[{"count":10,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/posts\/1213\/revisions"}],"predecessor-version":[{"id":1232,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/posts\/1213\/revisions\/1232"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=\/wp\/v2\/media\/1214"}],"wp:attachment":[{"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/innovatiestudio.hku.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}