|
Dear Sir,
First of all Thanking You for made such a good Project on waveInFFT in VC++. i got this source code from Code Project.
But now i have to build up something same work as u built in your work.i like to build programme with Audio Wave Player and find its FFT from that running Audio wave in VC++
How can i implement in my project work? i have no more idea how to build up FFT from that running wave file in my player.
So please be needful to me.
Reply as soon as possible.
Cheers,
Krunal Gajjar
krunal gajjar
|
|
|
|
|
Well basically you just copy the fft code from above, paste it into your program, then copy your wave samples into an array. Pass the array to the fft, and tell it how many samples are in the array. They should be a power of two. Then declare two variables for the output. The fft will return the real and imaginary output from the signal. Use the output through the intensity or some other function, and then use the result as you wish.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
Thankig You for Your kindly reply.
But In my wave player wave file run with 16 bit audio sample size, 2 channels and 44,000 hz sample rate.
Then how can i find an array and pass to the FFT as u told me. and which one FFT code i have to copy in my programme. and how can i get frequncy graph with programme.
plz needful to me.
Best Regrads,
Krunal
Whenever i find key to sucess, Someone changes the Lock
-- modified at 3:20 Tuesday 4th April, 2006
|
|
|
|
|
gkrunal wrote: Then how can i find an array and pass to the FFT
To find the array that you use to pass to the FFT, you would simply copy the sample values from your wave player, into an array and pass that new array to the FFT function. The code shows you how to create the array to pass to the FFT, the only difference is that I am using samples from recording the wave instead of playing. You just use the samples from your player instead, but the array passing would be the same.
gkrunal wrote: how can i get frequncy graph with programme
To get the frequency graph, you would take the output from the FFT, call getFrequencyInstensity and then use the output of the function as the height for the drawing code. The code should show you an example of how to accomplish this part.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
What adresses of ur soundcard are used in the example
and how do i modify them to my adresses.
And how can u see the frequenties that are lower then 100hz
Greetz
|
|
|
|
|
There are no addresses of soundcards used in my example. I am simply using the waveIn* functions to get the wave/mp3 audio passing through the system. To see frequencies lower that 100Hz you have to perform a FFT with a larger range of samples. The higher the number of samples used in the FFT the more frquency bands will be available, but also the longer it will take.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
-- modified at 8:58 Wednesday 29th March, 2006
|
|
|
|
|
I think the range of samples is declared in the function process
#define FFT_LEN 1024
butt if i change that number i get like a full screen of stripes
i actually want to see the frequenties that start from 0Hz What should i change if i wanted to see that. and i also dont have to see them over the 100 hz. How can i change the code to see that
Grtz
|
|
|
|
|
"The FFT analyzes a complex waveform into a large number of frequency bands. The bands are equally spread across the frequency spectrum, from 0 Hz to the Nyquist frequency. The number of bands is typically 512 or 1024. (The FFT algorithm requires that the number be a power of two.) Each band represents a sine wave of a certain frequency, and the amplitudes of these frequency components constitute the most important part of the analysis. The FFT assumes that the sound you analyze is constant, not changing."
This was taken from: http://www.indiana.edu/~emusic/courses/K503/Assign7S.html[^]
Therefore if you want only frequencies below 100Hz, you are not going to get it. You are going to get frequency bands, that include 200Hz, 2000Hz, etc. And you are going to get them in bands from 0Hz to the Nyquist frequency of the sampled sound. If you want more resoultion on the lower frequencies, then you are going to have to do an FFT with a higher length. Then you just discard the unneeded frequency bands. If you sample at 44100hz, that gives you a Nyquist frequency of 22050Hz. Divide that by the FFT length of 1024, results in a frequency bandwidth of 21.533203125Hz per sample. If you increase the length to 2048, you will get 10.7666015625Hz per sample. So if you want say 5Hz per sample you need a FFT length of 4096. Of course that will take much longer to perform, and may not be capable of being rendered in real time without the aid of a lot of processing power from a fast computer.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
This is all very interesting butt i would like to know where in the code those numbers must be changed. If u could be so kind to post the places where the code should be modyfied I would really appriciate it. Because am having trouble following ur actions.
Greetz
|
|
|
|
|
void fft_double (unsigned int p_nSamples, bool p_bInverseTransform, <br />
double *p_lpRealIn, double *p_lpImagIn, <br />
double *p_lpRealOut, double *p_lpImagOut)
p_nSamples should be equal to the FFT length you want 1024 is the default in FFTLEN . You set this to 2048 or whatever you need. Of course if you are going to set the number higher, then you it will require that you give the function more samples. You place your samples in the p_lpRealIn array.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
There is a function in the fourier source code:
double Index_to_frequency(unsigned int p_nBaseFreq, unsigned int p_nSamples, unsigned int p_nIndex);
I have not used this function, so I am not sure if the following is correct. But I beleive that you could use it as follows. Base Frequency recorded at 44100Hz, using 2048 samples. You could do something like:
#define FFT_LEN 2048
#define BASE_FREQUENCY 44100
for (int i=0; i < FFT_LEN/2; i++)
{
if (Index_to_frequency(BASE_FREQUENCY, FFT_LEN, i) < 100.0)
{
my100HzArray[i].real = fftReal[i];
my100HzArray[i].imag = fftImag[i];
}
}
inline double GetFrequencyIntensity(double re, double im)
{
return sqrt((re*re)+(im*im));
}
#define mag_sqrd(re,im) (re*re+im*im)
#define Decibels(re,im) ((re == 0 && im == 0) ? (0) : 10.0 * log10(double(mag_sqrd(re,im))))
#define Amplitude(re,im,len) (GetFrequencyIntensity(re,im)/(len))
#define AmplitudeScaled(re,im,len,scale) ((int)Amplitude(re,im,len)%scale)
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
Hello again
u speak of discarting frequentie bands. How can u do it in ur code.
So my question is actually how can i rewrite the code so i get only
the frequenties from 0 to 100 hz on the screen in de graphbox. If i
connect a sinus of 5 hz to my wave in I see on my screen a very little
bar in the box I would like it to be bigger so i can see it more clearly.
And how can i see an enlarged version of a signal that is only 1 mm on the screen
i need to see it bigger
Thx 4 ur help
Grtz
|
|
|
|
|
pietn321 wrote: u speak of discarting frequentie bands
You could do something like:
int nSamplingHertz = 44100;<br />
const int FFT_LEN = 2048;<br />
int nBandwidth = nSamplingHertz/FFT_LEN;<br />
for (int nBand =0; nBand < nBandwidth; n++)<br />
{<br />
myArray[nBand].real = re[nBand];<br />
myArray[nBand].imaginary = im[nBand];<br />
}
pietn321 wrote: And how can i see an enlarged version of a signal that is only 1 mm on the screen
i need to see it bigger
You would just change the drawing code to make the signal display wider. That would of course mean that you would pass the drawing code less frequency bands, which would be accomplished by removing unnessacary frequency bands as shown above.
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
-- modified at 10:03 Thursday 13th April, 2006
|
|
|
|
|
I really like this application but for some reason I see the bars moving even when there is no audio playing. Anyone knows why the application still shows some 'activity' even before/after playing the audio?
thank you.
|
|
|
|
|
You're probably seeing the background noise from your PC. I'm guessing because the input data is normalized before for the FFT so if you are looking at -85dB crackling it will look huge if there is no other audio at the input.
In other words, from what I've seen it's normal (4 different machines, different models and sound cards).
=^ D}
|
|
|
|
|
Hi,
I have a project which i am unable to do myself.It is not a very long project but because of the time constraint,I would like it to be completed at most by the 7th of November.
The specifications of the project are as follows:
I actually am developing a hearing aid and now the problem is in real time implementation of it.
1. I have to capture speech coming in through "mic in" port of the computer.
2. The captured speech would pass through a module(consisting of filters and Fourier transforms)..which i have written below.
3. The output through my module has to be played back out through the "mic out" port of the computer.
Code is :
#include <stdio.h>
#include <math.h>
#include <string.h>
double wdata[13]; //required for the FFT
double datafft[8192]; //length required is twice the inverse FFT
double x[295000]; //input data vector,maximum,length
int expo = 12; //required for the FFT
int main ()
{
double pi,ex,temp,theta1,coefa,coefb,G;
double X2,W1,bf,phikb,phia,phib;
double phi[1260],XR[4096],XI[4096],X[4096],XM[4096];
double w[512]; // vector of hamming window values
double ret[4096]; // vector of the inverse FFT returned data
double x1[512],x2[512],f[512];
double G1;
int a,i,j,k,m,n,FL,NW,L,l,q1,q2,kb,ks,ke;
double sr = 25000.0; // sampling rate
int CF = 15; // compression factor,CF:1
int hfru = 10500; // high frequency range upper limit
int hfrl = 4400; // high frequency range lower limit
int N = 2048; // number of frequency samples,top half
int ND = 512; // length of input data
int M = 4096; // length of inverse FFT
FILE *fp;
fp = fopen("ELPHRG01.WAV","r+b");
i = 0;
*/
while((fscanf(fp,"%f/n",&x[i++])) != EOF);
fclose(fp);
FL = i;
pi = 4.0 * atan(1.0);
ex = exp(1.0);
NW = 512;
W1 = 0.5;
l = 0;
L = 1;
for (n=0; n < NW; n++) {
theta1 = (2 * pi * n) / (NW - 1);
w[n] = W1 - (W1 * cos(theta1));
}
for (n = 0; n < NW; n++) {
x2[n] = 0.0;
}
bf = sr / (2 * CF); // break frequency
phikb = (pi * bf) / (sr / 2); // angle of break frequency
kb = N / CF; // number of samples from DC to break
phia = (hfrl / (sr /2 )) * pi; // high frequency region starting angle
phib = (hfru / (sr /2 )) *pi; // high frequency region ending angle
coefa = 0.00799;
coefb = -0.3722072;
//1. Obtain a windowed Segment of the input data
for (a = 1; a < 2 * FL / NW + 1; a++) {
for (m = 0, n = 1; m < NW; m++, n++) {
f[m] = w[m] * x[n];
}
}
//2. Obtain Nonlinearly Compressed and Transpossed frequency samples
for (k = 0; k < 150; k++) {
temp = coefa * k;
phi[k] = pow(ex, temp) + coefb;
G = pow(ex, temp);
G1 = G * sqrt(G) + 6;
XR[k] = 0.0;
XI[k] = 0.0;
for (n = 0; n < ND; n++) {
XR[k] = XR[k] + f[n] * cos(phi[k] * n);
XI[k] = XI[k] + f[n] * sin(phi[k]*n);
}
XR[k] = G1 * XR[k];
XI[k] = G1 * XI[k];
}
//3. Pad zeros in the center of the Spectrum
for (k = 150; k < M - 150; k++) {
XR[k] = 0.0;
XI[k] = 0.0;
}
//4. Form the Complex conjugate part of the spectrum
for (k = M - 150 + 1; k < M + 1; k++) {
XR[k] = XR[M-k];
XI[k] = -XI[M-k];
}
//5. Convert from Polar to rectangular for the inverse FT
for (i = 0; i < M; i++) {
j = 2 * i;
k = j + 1;
datafft[j] = XR[i];
datafft[k] = XI[i];
}
//6. Call the FFT
f_init(); //I need to implement this FFT function in C++ rather than Foxpro
MAIN_();
//7. Obtain the inverse FFT from the FFT call
ret[0] = datafft[0] / M;
for (i = 2244; i < 2756; i++) {
j = 2 * i;
k = 2 *M - j;
ret[i+1] = datafft[k] / M;
}
for (k = 0; k < 512; k++) {
ret[k] = ret[k+2244];
}
// Multiply by the hamming
q1 = a / 2;
q2 = q1 * 2;
if (q2 == a) {
for (i = 0; i < 256; i++) {
X2 = ret[i] * w[i] + x1[i + 256];
printf("%f\n",X2);
}
for (i = 256; i < 512; i++) {
x2[i] = ret[i] * w[i];
}
} else {
for (i = 0; i < 256; i++) {
X2 = ret[i] * w[i] + x2[i + 256];
printf("%f\n",X2);
}
for (i = 256; i < 512; i++) {
x1[i] = ret[i] * w[i];
}
}
l = (NW * L / 2);
L = L+1;
return 0;
}
MAIN_()
{ //This is again using Fox Pro but i am not sure
fft2c_(datafft,&expo,wdata);
return 0;
}
So,in all i just need code development in C++ to capture speech and play it back and a slight modification in my module to make it compatible.
If somebody can please help me out,I am even willing to pay for the project.
Thanks,
Student
|
|
|
|
|
Can anyone show how to modify the code, to preform FFT on wave out audio signal?
|
|
|
|
|
In have been visiting nearly everyday. To see if anyone/someone could answer (WaveOUT), because I also wants to know! - Is this CodeProject dead?
|
|
|
|
|
The WaveOUT process is the same with the WaveIN, just the audio data source is different, this article just show the FFT of audio signals.
good lucks.
|
|
|
|
|
It's easy job,just put the code Process() to before waveOutPrepareHeader
|
|
|
|
|
How do you use reverse FFT ?
When you do this :
fft_double(FFT_LEN,0,fin,NULL,fout,foutimg);
you get real and imaginary part of signal in fout[] and foutimg[].
Should the reversal look like this ?
fft_double(FFT_LEN/2,1,fout,foutimg,fin,NULL);
Will the reverse FFT return an imaginary part?
Thank's!
Peter
|
|
|
|
|
piotreq wrote: When you do this :
fft_double(FFT_LEN,0,finBefore,NULL,fout,foutimg);
you get real and imaginary part of signal in fout[] and foutimg[].
Should the reversal look like this ?
fft_double(FFT_LEN/2,1,fout,foutimg,finAfter,NULL);
Will the reverse FFT return an imaginary part?
Its been a long time since I looked at this code so forgive me if my memory is a bit rusty. Your code:
fft_double(FFT_LEN,0,finBefore,NULL,fout,foutimg);
will take FFT_LEN samples from fin, and return exactly that many samples of real data in fout, and exactly the same amount in foutimg. Therefore if you want to do the inverse fft, sometimes shortened to IFFT Then you need to pass the fft the real and imaginary parts of the signal, along with the number of samples in each. Then you will get a real part result with the original signal. The imaginary portion of the output will simply be zero so you can pass null for it. So instead of:
fft_double(FFT_LEN/2,1,fout,foutimg,finAfter,NULL);
It should be:
fft_double(FFT_LEN,1,fout,foutimg,finAfter,NULL);
And if the code is working correctly, finAfter should equal finBefore...
Hope that helps... sorry for the late reply...
Nothing is impossible, It's merely a matter of finding an answer to the question of HOW? ... And answering that question is usually the most difficult part of the job!!!
|
|
|
|
|
ı can get sound from sound card of my pc by using waveInxxx api.but ı want to get this sample value of this sound and want to show my listbox..
|
|
|
|
|
Hi,
I've written a renderer filter which produces a spectral analysis, the output is fine when the graph is:
[source filter]->[wave parser]->[my filter]
but in this case there is no sound, which is of little use.
When the graph looks like:
[source]->[wave parser]->[Tee filter]->[my filter]
....................................->[default directsound dev]
this provides both output and analyser but the analyser is jerky, is there anyway to make it run a little smoother?
The oscilloscope filter from the SDK also suffers from the same problem.
|
|
|
|
|
hello. I've got a problem writting up algorithm for FFT. I've got a 26 seconds length of audio signal, samplae at 22050Hz, 8 bits, the frequency increases as time increases. now, what am I trying to do is to extract the frequency at each second, e.g. - frequency at 1 sec, 2 sec, 3 sec, and so forth. here is my coding. but this only displayed frequency at 1 second.
fs = 22050; % Sampling frequency.
bits = 8; % number of bits per sample, 256 levels.
[x,fs,bits]=wavread('SS1stE01.wav');
%FFT
N = 32768;
yf = fft(x,N);
resolution = fs/N;
f = resolution*(1:N/2);
y=yf(1:N/2);
plot(f,abs(y));
title ('Frequency content of SS1stE01.wav');
xlabel('Frequency(Hz)');
ylabel('Amplitude');
thank you.
|
|
|
|
|