Old 07-10-2018, 12:25 PM   #1
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
Default Looking at FFT Splitter, but not getting a small part...

There is the JSFX:FFT splitter, written by Schwa, that uses FFT to split the input into two parts and sending the parts out on different channels. I think I understand most of it, except a small (or maybe big) thing.

The relevant parts of the code look like this:

Code:
    fft(buf1, fftsize);
    fft_permute(buf1, fftsize);
 
    memcpy(splitLo1+2, buf1+2, splitfreq);
    memset(splitLo1+splitfreq+2, 0, 2*(fftsize-splitfreq-1));
    memcpy(splitLo1+2*fftsize-splitfreq, buf1+2*fftsize-splitfreq, splitfreq);

    // Removed code calculating values for bins 0 and 1 of the splitLo1 buffer

    memset(splitHi1, 0, splitfreq+2);
    memcpy(splitHi1+splitfreq+2, buf1+splitfreq+2, 2*(fftsize-splitfreq-1));
    memset(splitHi1+2*fftsize-splitfreq, 0, splitfreq);  

    // Removed code calculating values for bins 0 and 1 of the splitHi1 buffer

    fft_ipermute(splitLo1, fftsize);
    fft_ipermute(splitHi1, fftsize);
    ifft(splitLo1, fftsize);
    ifft(splitHi1, fftsize);
splitfreq is the frequency at which to split the incoming audio into the low and high halves. The FFT is done from and to buf1, from which then the low part, splitfreq number of bins, is copied into the splitLo1 buffer, and the high part, 2*(fftsize-splitfreq-1) number of bins, is copied into the splitHi1 buffer.

However, the splitLo1 buffer also gets bins copied into its upper part in the second memcpy. What's up with that?

I expected the low bins, representing the frequencies below splitfreq, to be copied to splitLo1, and the high bins, representing the frequencies above splitfreq, to be copied into splitHi1. And of course, that does happen, but then there is the third set of bins (splitfreq number of them) copied from buf1 into the uppermost part of splitLo1. That small part I do not get...
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 07-10-2018, 01:12 PM   #2
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
Default

As the transform always is symmetrical, you need to create the bins higher than the samplerate accordingly.

-Michael
mschnell is online now   Reply With Quote
Old 07-11-2018, 03:31 AM   #3
Fabian
Human being with feelings
 
Fabian's Avatar
 
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
Default

Quote:
Originally Posted by mschnell View Post
As the transform always is symmetrical, you need to create the bins higher than the samplerate accordingly.

-Michael
Thanks.

I'm not sure I get that, though, or how it answers my question. Probably my question was ill-posed, or I really do not understand this as I thought.

fftsize decides the number of bins, right? And each bin is a tuple of (re, im), so each buffer is the size of 2 * fftsize (and we can assume fftsize to be 8192). The max frequency is given by Nyquist (he was Swedish, btw ) to be half the sample rate, so in my case 22 050 Hz. Thus, each bin will represent ~2.7 Hz.
After fft and permutation, buf1 has the 0 Hz (DC) values in buf1[0] and buf1[1], the 0 to 2.7 Hz values in buf1[2] and buf1[3], and so on up to the 22 047 to 22 050 Hz values in buf1[16382] and buf1[16383], right?

Or are you saying that, after fft and permute, there is something up there in the top part of buf1 that is above the Nyquist frequency? If so, this totally wrecks my understanding of how things work...

Sorry if this is a noob question. I looked at most of the posts on FFT here in the forum, looked at wikipedia, and googled in general, but I could not find anything that looked like coming close to explaining what goes on here.

Thanks.
__________________
// MVHMF
I never always did the right thing, but all I did wasn't wrong...
Fabian is offline   Reply With Quote
Old 07-11-2018, 08:01 AM   #4
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
Default

I erroneously said " higher than the samplerate". Above the Nyquest frequency (which is half the sample rate) would have been correct.

It's symmetrical within the sample rate (i e the count of bins / FFT-(window)-size) folding at the Nyquist frequency.

I.e. you can shift down the spectrum by the sample rate and access the low (i.e. all) frequencies at the negative frequency bin (bin[-1], bin[-2], ...

Sorry,
-Michael

Last edited by mschnell; 07-12-2018 at 06:43 AM.
mschnell is online now   Reply With Quote
Old 07-11-2018, 11:31 AM   #5
mschnell
Human being with feelings
 
mschnell's Avatar
 
Join Date: Jun 2013
Location: Krefeld, Germany
Posts: 14,690
Default

More precisely:

Digital FFT transforms a complex periodic function to a complex periodic function.

If the source is real, the target is symmetrical.

The period of the source is the FFT window size divided by the sample rate (i.e FFT-size samples). That is why you need to do an overlapping window algorithm to convert a non periodic signal.

The "DC" bin "0" hods the signal part with all frequencies lower than the periodicy dictated by the window size and hence - for doing a low pass filter - the real part of same usually should not be cleared, passing these frequencies unmodified. (The imaginary part of bin "0" by definition holds the real part of the Nyquist, which usually is very close to zero anyway).

The period of the target is the sample rate. (I.e. Window size count of bins.)

The symmetry of the target (if the source is real) is at zero, and hence due to periodicy also at half the sample frequency etc.

You can take advantage of the source being real by adding a second channel as the imaginary part and do a single convert for both.

Or you can use the "real FFT" call provided by the JSFX framework to do the conversion of a mono single more than twice as fast.

-Michael

Last edited by mschnell; 07-12-2018 at 06:47 AM.
mschnell is online now   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 02:32 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.