techPowerUp! Forums (http://www.techpowerup.com/forums/index.php)
-   Programming & Webmastering (http://www.techpowerup.com/forums/forumdisplay.php?f=52)
-   -   FFT question - again.. (http://www.techpowerup.com/forums/showthread.php?t=180067)

 ste2425 Feb 12, 2013 08:26 AM

FFT question - again..

Well i posted a question not too long ago about FFT's as im building a automatic feedback suppressor for my final year project at university. Well ive developed all the various sections, the bit where it detects feedback during a sort of auto-ringing out procedure, the bit where it monitors the frequencies to see if detected feedback frequencies are reaching the threshold where they begin to feedback and the section that actually deals with the audio samples and cuts the various frequencies.

All of this has been developed in Matlab and im confident with my code just need to port it over to the VST SDK in C++ with just syntax and other little issues like how they address arrays etc.

Right my question. In Matlab due to my sound card its sampling frequency is 8K now thanks to Mr Nyquist my highest detectable frequency is 4K which means my FFT isn't too large to calculate at a resolution high enough for that band of frequencies, 20Hz - 4K. However when i roll this out to the VST SDK ill be working up to the full 20K so the required FFT size will be much much larger for the same resolution and wile processing the audio in real time this won't be plausible.

Now my possible solution, i don't know if this is pioneering stuff here or a current method already about, is to band limit the audio spectrum into maybe three bands. Perform a much smaller FFT to get the same resolution on these bands then collate the results from each to hopefully get the same resolution of the audio spectrum as a whole with, hopefully much smaller computing requirements.

My issue with this is to calculate the frequencies of your bin's from the FFT you:

Bin no * FFT size / Sampling Frequency

However this assumes that the full frequency spectrum is being passed through it so how would i adjust this to reflect the band limited input? I'm assuming it has something to do with the Sampling Frequency value.

Now i haven't done any form of testing on this idea, currently at University and it just poped into my head now, but i will be having a play with it tonight and hoped for some points from you guys of where to start to make quicker or even a name of the method if this process is common place.

Thanks all :toast:

 1freedude Feb 12, 2013 10:25 AM

It looks like you are on the edge of some serious graduate level work. Congratulations, you are trying to build already patented technology, no sarcasm meant. Sabine has this hardware already.

Seriously, keep it up. Its guys like you that make the world cheaper and better.

I wish my Matlab was stronger. My avatar is a simple .m file of the values of pi/720 from -pi to pi in a pie chart! I tic toc'd it and ran it as a benchmarch on different systems.

 Fourstaff Feb 12, 2013 11:15 AM

Wouldn't you just feed a limited frequency to each bin rather than feeding the entire frequency into each? I am not sure how you would selectively choose which frequency to take in. (no I haven't give much thought about it yet).

 qubit Feb 12, 2013 11:31 AM

Ok, I can only guess at the answer to your question, but I've thanked you just for asking such an awesome question!

I doubt that splitting the frequencies like that will work in the way you expect, since I believe the whole 20Hz-20KHz frequency band needs to be processed as a whole to get a full band result.

Having said that, many times there are shortcuts to solving problems and it's possible that for the specific function you're trying to implement, this would be fine. Perhaps a really narrow FFT would be fine for this project?

Also, could you please clarify what you mean by feedback? Are we talking about the sort of thing where a microphone is placed too close to a speaker? If so, an FFT focused on a narrow band of frequencies might work perfectly, since that characteristic squeal to tends to happen at more or less the same frequencies each time.

Hope this helped! :)

 ste2425 Feb 18, 2013 12:28 AM

Thank you all for the kind comments and encouragement. Ive thrown my self in the deep end with this project i have a total of about four weeks to finish this and im no where near that. All my code is ready im just struggling to get it into VS.

I have a total of about 18 months of experience programming most of which gained about one and a half years ago.

Due to the steinberg VST SDK it creates a .dll which is the file you load into the host programe logic pro, cubase etc to use the VST. Now my problem is, and im guessing its because there is no int main combined with the fact the file being run is a .dll functions like cout or anything that requires a console do nothing. They compile perfectly fine but have no effect. Due to the need for the host program to effectively operate the VST, controlling how many samples to hand it, take from it etc i cannot debug within Visual Studio (VS) so its becomeing very very difficult to work out what my variables are doing as there is no way for me to view their contents.

Hope that makes sense and i haven't spelled too many words wrong. Im extremely tired All the letters are just jumbling up and making no sense. The point of all of this is in the hope that any of you guys know what im missing to make the VST produce a command window which i can printf or cout variables to as the program is running to provide me with some form of debug functionality.

Thanks

 1freedude Feb 18, 2013 03:34 AM

Why go to C++? What about C?

 ste2425 Feb 18, 2013 07:26 AM

Quote:
 Originally Posted by 1freedude (Post 2847754) Why go to C++? What about C?
My friend at uni has gone C and i wish i had. But i feel i don't have the time now. Setting up the SDK in C++ was slightly time consuming and all of that 18 months experience was gained within visual studio using C++ as part of my course. Whilst i know that C and C++ are quite similar is some respects, and from what ive read, quite the opposite in others. I think the task of starting this again in C whilst learning all those differences within the time frame ive got left to do this is a larger task.

Thanks for the advice though :toast: If i could just work out how to produce a dam command window all of this would be fine.

EDIT: now i feel daft i never realized that you can link a process running a .dll file or just a running process in general and debug that within visual studio to see the contents of all the variables. Ive now found out my FFT is working just need to adjust it slightly and apply windowing but it actually functions well chuffed the rest should be easy now i can debug it very happy :)

 ste2425 Feb 21, 2013 10:52 AM

quick question i have a multidimensional array which is storing my fft results over time each column being the results from the fft. Now ive seen a swap function which can transfer the data from one array to another but is there a function to shift the columns down when i wish to enter the latest fft result? So say the no of columns is 5. data from column index 4 will be shifted to 3, 3 shifted to 2, 2 shifted to 1, 1 shifted to 0 and the data that was originally in 0 deleted leaving column 4 empty or at least filled with what ever it puts there ready for me to fill it with my fft results?

It would make life easier if there was a function to do this, if not i can easily make up a little function to do so.

 Fourstaff Feb 21, 2013 11:08 AM

Just write a loop sending 5 to 4, 4 to 3, 3 to 2 and 2 to 1, and then add data to 5th column. Use While loop, sometimes faster. As long as array dimensions does not change it will be done in no time.

Edit: Or you can write a function sending 2:5 to 1:4, and then input a new 5, doing away with a silly loop

 Aquinus Feb 21, 2013 12:57 PM

Quote:
 Originally Posted by ste2425 (Post 2850898) quick question i have a multidimensional array which is storing my fft results over time each column being the results from the fft. Now ive seen a swap function which can transfer the data from one array to another but is there a function to shift the columns down when i wish to enter the latest fft result? So say the no of columns is 5. data from column index 4 will be shifted to 3, 3 shifted to 2, 2 shifted to 1, 1 shifted to 0 and the data that was originally in 0 deleted leaving column 4 empty or at least filled with what ever it puts there ready for me to fill it with my fft results? It would make life easier if there was a function to do this, if not i can easily make up a little function to do so.
Quote:
 Originally Posted by Fourstaff (Post 2850910) Just write a loop sending 5 to 4, 4 to 3, 3 to 2 and 2 to 1, and then add data to 5th column. Use While loop, sometimes faster. As long as array dimensions does not change it will be done in no time. Edit: Or you can write a function sending 2:5 to 1:4, and then input a new 5, doing away with a silly loop
I agree with Fourstaff but it be helpful to know what you're trying to do (mathematically,) when you're shifting this away. I'm trying to conceptualize what you're doing and I'm having a hard time putting all of it together which will render any recommendation I make partially moot.

So if you had a multi-dim array like this:
Code:

```[ A, B, C ] [ D, E, F ] [ G, H, I ]```
We will call this array N.
When I refer to array indices the top left is 0,0 with the top right being 2,0. (Think x and y)

You want to transform it in a way where array N has its elements shifted so elements get moved from (x, y) => (x-1, y-1) where x > 0 and y > 0.

So you maybe want something like this?

Code:

```void shift(int x, int y, int * arr) {     int xc, yc;     // The corners go to zero since nothing can ever be moved into them.     *(arr + (x - 1)) = 0;     *(arr + (y * (x - 1))) = 0;     // Start at 1,1. The first place an element will get moved to another place     // in the array.     for(yc = 1; yc < y; yc++) {         for(xc = 1; xc < x; xc++) {             *(arr + ( (yc - 1) * x ) + (xc - 1)) = *(arr + (yc * x) + xc);             if( (xc + 1) >= x | (yc + 1) >= y) {                 // New values go here, zero them out for now.                 *(arr + (yc * x) + xc) = 0;             }         }     }```
I made a quick little C application to try it out and it does this. The first table output it the array before shift is called and the second is after.

Code:

```~\$ ./a.out ---- START TABLE ---- [  1804][  846][  1681][  1714][  1957] [  424][  719][  1649][  596][  1189] [  1025][  1350][  783][  1102][  2044] [  1967][  1365][  1540][  304][  1303] [    35][  521][  294][  1726][  336] ----- END TABLE ----- ---- START TABLE ---- [  719][  1649][  596][  1189][    0] [  1350][  783][  1102][  2044][    0] [  1365][  1540][  304][  1303][    0] [  521][  294][  1726][  336][    0] [    0][    0][    0][    0][    0] ----- END TABLE -----```
I hope this is helpful. It's been quite some time since I've written some C.

 ste2425 Feb 22, 2013 03:38 PM

That is top notch my friend i really didnt expect anyone to take the time to write any sort of code up and even test it. Its greatly appreciated you taking the time. I didn't explain it very well. But you hit the nail on the head with you code, whilst i only need to move data on the y axis keep its x axis the same it does exactly what i need.

I was in a little bit of a rut with this. Id defined a count variable within the processReplacing() which handles the actual audio samples. The counter would count up everytime my buffer is full only i couldnt work out why it would count up to three and stop. I didnt realise the variable is re initialized (if thats the right term) every time the host calls the function with the new input buffer meaning my buffer was filling up as it should except the counter was being reset every time the function was called. Anyhoo stuck my counter variable within the VST class making it global and now all is dandy very pleased.

Currently it detects the feedback through ringing out, it boost the output signal over time to try and create feedback detects if there is one or more frequencies feeding back, detects their peaks and notes what amplitude they first start to feedback at to create a threshold to ensure they don't go over and cause feedback. If the signals fall below they are allowed to rise back up with no form of filter applied its only when they go over the threshold they are cut and only by enough to keep below that threshold.

However this method means its oblivious to any frequencies that could feedback after that ringing out phase however i have a few ideas to combat that :)

Watch this space.

 Aquinus Feb 22, 2013 03:51 PM

Quote:
 Originally Posted by ste2425 (Post 2852004) That is top notch my friend i really didnt expect anyone to take the time to write any sort of code up and even test it. Its greatly appreciated you taking the time. I didn't explain it very well. But you hit the nail on the head with you code, whilst i only need to move data on the y axis keep its x axis the same it does exactly what i need.
No problem, I'm happy to help. As far as doing mathematical processing on a computer, doing linear algebra and mucking with matricies is one of my more favorite topics. I like dabbling in it when I have some spare time. I'm glad that at least part of it was useful. As a programmer you tend to get good at understanding what people mean when they describe something that they want programmed. You might not always hit it right on the head but more often than not you're close enough and the more you do it the better you get at interpretting those instructions. :)

Anyways I'm glad you're making progress. We're here if you have any questions and we can do our best to answer them. Cheers! :toast:

 ste2425 Feb 24, 2013 02:07 PM

http://img.techpowerup.org/130224/zsdrhfdshg.jpg

Small update been working on the fun visual stuff for a little bit of a break with dealing with loops if statements and classes :p Currently the GUI is automated in the the ringing out button, far right automates the main mix out fader as it boosts the output gain. When the ringing process is started the ring out button stays locked down until it is finished then its released. Theres also a lock button, the red circle next to the ring out button, when red you can ring out the system when its green the ring out button is locked and the system carn't be rung out, this is so you don't accidentally press it and ring your system out mid concert. The black square will hold status LED's for all the filters, so far im thinking 30 in total. The Power switch also stops the FFT function being called, whilst its not overly compute intensive on older machines user might not want it using resources when its turned off. The buffer for the fft is constantly being filled regardless of whether the system is on or bypassed then there's not a delay before the first FFT waiting for it to fill.

Sadly graphic design is not my strongest point but im pleased to say i did it in paint.

 ste2425 Mar 3, 2013 11:38 AM

Another question im trying to record the filters out put to use other software to measure it and see if my software reports the same etc. Now i have my mixer plugged in through usb, the VST host is set up to take the mixer as its input and send the output through my onboard out. Is there a way to mimic the onboard out as though it was a line in on my motherboard so i can record it?

That is without the input from my mixer? so i just records the output of my onboard audio and therefore just records the output of my filter? hope that makes sense.

Sadly i dont have a mini jack to mini jack to just loop through from my headphones to line in otherwise id just do that :)

 Aquinus Mar 3, 2013 11:42 AM

Quote:
 Originally Posted by ste2425 (Post 2857615) Is there a way to mimic the onboard out as though it was a line in on my motherboard so i can record it?
Not without tying the output of one device to the input on another. To build this without doing that you would need a virtual audio device if you will and programming that could be a pain. I'm not sure if there is anything like this on the internet that could help you do it this way.

 ste2425 Mar 3, 2013 11:48 AM

Ahh looks like ill be running to my local audio store :p

Well heres a run down of whats happening to keep you all updated :)

The feedback detection part is working fine its detecting the feedback and the magnitude in db that it starts. (ive tested this at university where i had the means to record the output of it.)

Now that data is sent to a notch filter to cut by the center frequency given and a number to cut it by to bring the offending frequency below the threshold where it starts to feedback. However the scaling of the cutting value seems to be out so im manually giving the notch filter values of what should be say a 10 dB cut and trying to record and analyse the output to see if it is actually cutting my that 10dB.

Then ill hopefully be able to work out correct values that should be sent to the notch filter to give the correct level of cut. Hope that makes sense :)

EDIT: 4/3/2013: Dam im a fool. Issue with the notch filter was that my difference equation requires the current sample, one sample previous to the current and the second sample previous to the current to multiply the coefficients by. Issue was when i wanted one sample previous i was giving it the second sample previous and vice versa. I must have looked over it so many times and not realized. Anyhoo all is good in the hood now.

 ste2425 Mar 5, 2013 10:58 PM

quick video of initial functions. Consider it version 1.0 :)

 All times are GMT. The time now is 07:42 PM.