<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">Looking closer, it appears the OOURA fft has special routines for n<64... but it uses those routines regularly as subroutines in larger ffts. In any case it looks like the smaller block sizes are intended to be usable in the code itself, but Miller must've had a reason not to trust them. Here's the main OOURA complex fourier transform subroutine, which calls a bunch of others, which all call smaller ones. The Pd prologue code would make sure that none of the smaller cases at the bottom would ever be called.</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">=======================================</div><div class="gmail_default" style="font-family:verdana,sans-serif"><div class="gmail_default">void cftfsub(int n, FFTFLT *a, int *ip, int nw, FFTFLT *w)</div><div class="gmail_default">{</div><div class="gmail_default">    void bitrv2(int n, int *ip, FFTFLT *a);</div><div class="gmail_default">    void bitrv216(FFTFLT *a);</div><div class="gmail_default">    void bitrv208(FFTFLT *a);</div><div class="gmail_default">    void cftf1st(int n, FFTFLT *a, FFTFLT *w);</div><div class="gmail_default">    void cftrec4(int n, FFTFLT *a, int nw, FFTFLT *w);</div><div class="gmail_default">    void cftleaf(int n, int isplt, FFTFLT *a, int nw, FFTFLT *w);</div><div class="gmail_default">    void cftfx41(int n, FFTFLT *a, int nw, FFTFLT *w);</div><div class="gmail_default">    void cftf161(FFTFLT *a, FFTFLT *w);</div><div class="gmail_default">    void cftf081(FFTFLT *a, FFTFLT *w);</div><div class="gmail_default">    void cftf040(FFTFLT *a);</div><div class="gmail_default">    void cftx020(FFTFLT *a);</div><div class="gmail_default">#ifdef USE_CDFT_THREADS</div><div class="gmail_default">    void cftrec4_th(int n, FFTFLT *a, int nw, FFTFLT *w);</div><div class="gmail_default">#endif /* USE_CDFT_THREADS */</div><div class="gmail_default">    </div><div class="gmail_default">    if (n > 8) {</div><div class="gmail_default">        if (n > 32) {</div><div class="gmail_default">            cftf1st(n, a, &w[nw - (n >> 2)]);</div><div class="gmail_default">#ifdef USE_CDFT_THREADS</div><div class="gmail_default">            if (n > CDFT_THREADS_BEGIN_N) {</div><div class="gmail_default">                cftrec4_th(n, a, nw, w);</div><div class="gmail_default">            } else </div><div class="gmail_default">#endif /* USE_CDFT_THREADS */</div><div class="gmail_default">            if (n > 512) {</div><div class="gmail_default">                cftrec4(n, a, nw, w);</div><div class="gmail_default">            } else if (n > 128) {</div><div class="gmail_default">                cftleaf(n, 1, a, nw, w);</div><div class="gmail_default">            } else {</div><div class="gmail_default">                cftfx41(n, a, nw, w);</div><div class="gmail_default">            }</div><div class="gmail_default">            bitrv2(n, ip, a);</div><div class="gmail_default">        } else if (n == 32) {</div><div class="gmail_default">            cftf161(a, &w[nw - 8]);</div><div class="gmail_default">            bitrv216(a);</div><div class="gmail_default">        } else {</div><div class="gmail_default">            cftf081(a, w);</div><div class="gmail_default">            bitrv208(a);</div><div class="gmail_default">        }</div><div class="gmail_default">    } else if (n == 8) {</div><div class="gmail_default">        cftf040(a);</div><div class="gmail_default">    } else if (n == 4) {</div><div class="gmail_default">        cftx020(a);</div><div class="gmail_default">    }</div><div class="gmail_default">}</div><div class="gmail_default">=======================================<br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 16, 2015 at 7:43 PM, Robert Esler <span dir="ltr"><<a href="mailto:robert@urbanstew.org" target="_blank">robert@urbanstew.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Sorry I checked your patch again.  I get the same behavior.  I had an older version of Pd I was using.<div><br></div><div>Yes, I just noticed this too.  It appears OOURA limits the calculation to a block size of 32 or higher.  Why?  The code is so horribly documented I’d rather not even try to figure it out.  </div><div><br></div><div>Pd also has the option of using the FFTW3 library by Thomas Grill, which on a surface reading doesn’t seem to have a block boundary.  But I can’t be sure w/o trying it.  Of course this would require a manual compiling of Pd.</div><div><br></div><div>Not sure why the mayer fft lib was removed, but this is one of the few instances of Pd breaking older patches.  Maybe this needs to be a dev request?  At the very least print an error to the Pd window.  </div><div><br></div><div>-Rob<br><div>
<div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><br></div><div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word">P.S - I have a C++ version of the old mayer_fft that I could probably wrap into a Pd object if it seems like this is a big enough problem.</div><div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:-webkit-auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><br></div>
</div><div><div class="h5">
<br><div><blockquote type="cite"><div>On Oct 16, 2015, at 4:09 PM, Matt Barber <<a href="mailto:brbrofsvl@gmail.com" target="_blank">brbrofsvl@gmail.com</a>> wrote:</div><br><div><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">OK, looking at the OOURA code, the init routine has this:</div><div class="gmail_default" style="font-family:verdana,sans-serif"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif">========================</div><div class="gmail_default"><div class="gmail_default" style="font-family:verdana,sans-serif">static int ooura_init( int n)</div><div class="gmail_default" style="font-family:verdana,sans-serif">{</div><div class="gmail_default" style="font-family:verdana,sans-serif">    n = (1 << ilog2(n));</div><div class="gmail_default" style="font-family:verdana,sans-serif">    if (n < 64)</div><div class="gmail_default" style="font-family:verdana,sans-serif">        return (0);</div><div style="font-family:verdana,sans-serif">========================</div><div style="font-family:verdana,sans-serif"><br></div><div style="font-family:verdana,sans-serif"><br></div><div style="font-family:verdana,sans-serif">then later in the fft/ifft routine:</div><div style="font-family:verdana,sans-serif"><br></div><div style="font-family:verdana,sans-serif">========================</div><div><div><font face="verdana, sans-serif">     if (!ooura_init(2*n))</font></div><div><font face="verdana, sans-serif">        return;</font></div><div><font face="verdana, sans-serif">========================</font></div><div><font face="verdana, sans-serif"><br></font></div><div><font face="verdana, sans-serif">and rfft:</font></div><div><font face="verdana, sans-serif">========================</font></div><div><font face="verdana, sans-serif"><div>    if (!ooura_init(n))</div><div>        return;</div><div>========================</div><div><br></div><div><br></div><div><br></div><div>since these operate directly on samples in the signal vector, it will pass signals in small blocks without performing dft. I don't know what this is supposed to avoid. I've used fft in small block sizes before, and I can't be the only one whose patches might be broken by this.</div><div><br></div><div><br></div></font></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 16, 2015 at 5:33 PM, katja <span dir="ltr"><<a href="mailto:katjavetter@gmail.com" target="_blank">katjavetter@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If I understand the fft files correctly OOURA is now the default, but<br>
'disguised' as mayer fft so the old API should remain valid.<br>
(<a href="http://sourceforge.net/p/pure-data/pure-data/ci/master/tree/src/d_fft_fftsg.c" rel="noreferrer" target="_blank">http://sourceforge.net/p/pure-data/pure-data/ci/master/tree/src/d_fft_fftsg.c</a>).<br>
<br>
Indeed I get the same result for Matt's test patch with Pd 0.46-5<br>
which is on my system. Sinusoids for block size 8 and 16, instead of<br>
spectrum points.<br>
<br>
A while ago I've been reading in OOURA fft code and what I remember<br>
is, Pd uses its mixed radix functions. Not sure about it though.<br>
<br>
Katja<br>
<div><div><br>
<br>
On Fri, Oct 16, 2015 at 10:00 PM, Robert Esler <<a href="mailto:robert@urbanstew.org" target="_blank">robert@urbanstew.org</a>> wrote:<br>
><br>
>   As far as I know Pd stopped using the mayer fft library in .46, which is probably why this is new behavior.  I only get what you’re experiencing with a block size of 8.  Otherwise, it seems to perform as expected.<br>
>   To really understand if this is a bug or not is to know which fft library is being used for OS X.   My guess is it’s the OOURA but it’s not clear from looking at [fft~] object code that comes with distribution.<br>
>   You could also download the old library and recompile Pd, but I doubt it’s worth it.<br>
> -Rob<br>
> -------<br>
> Hi list,<br>
><br>
> There's either a major bug in the [fft~] objects in Pd-0.46.7 (64bit OSX)<br>
> or I'm going crazy. I'd love to see if others can reproduce it.<br>
><br>
> Basically, for [block~] sizes less than 32 bits, [fft~] doesn't perform --<br>
> it just passes the signal through unchanged. [ifft~] does the same. The<br>
> [rfft~]-[rifft~] is a little more complicated -- it passes signal through<br>
> but zeroes out the last N/2 for [block~] sizes less than 64.<br>
><br>
><br>
> See the attached patch, which only shows [fft~]. The saved contents of the<br>
> tables on opening are the results for [block~ 8] on my machine, for<br>
> quarter-nyquist at 44100.<br>
><br>
> I've never seen this before in other versions of Pd. Anyone else get this<br>
> behavior?<br>
><br>
> Matt<br>
</div></div>> _______________________________________________<br>
> <a href="mailto:Pd-list@lists.iem.at" target="_blank">Pd-list@lists.iem.at</a> mailing list<br>
> UNSUBSCRIBE and account-management -> <a href="http://lists.puredata.info/listinfo/pd-list" rel="noreferrer" target="_blank">http://lists.puredata.info/listinfo/pd-list</a><br>
</blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></div></blockquote></div><br></div>