|
I have been waiting for this, but it doesn't do anything and same situation is here. I have downloaded the real play, but where “u should set your recording source to "stereo mix" or "mono mix" in recording control” ?
Agha Khan
|
|
|
|
|
Sorry for the late reply. But I have extremely busy with other projects. Often working 20 hours a day. To anwser your question, Yes you have to go the recording properties of your soundcard, and specifically select the mono/stereo mix or wave mix option in the recording section of your soundcard. Also you must have the wave playback not set to mute or else that will override the selection of the recording properties.
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!!!
|
|
|
|
|
Thanks friend. This is an excellent stepping stone for me. I was trying to learn how to use the FFT to make Spectrum Analysers
Amit
|
|
|
|
|
Is anyone know how to solve this problem. I have just downloaded your code and executed in my platform. My Visual C++ is VC++.NET and it has below errors. I think it is a very minor error but I can't solve it easily. Help me. Thanks in advence.
c:\waveInFFT_demo\SpectrumGraph.cpp(169): error C2668: 'log10' : ambiguous call to overloaded function
Have a good day.
|
|
|
|
|
log10 function is expecting a float or double value, but complier is confused about what type of value it should consider.
Replace it from
y=log10(x/rct.Width());
to
float fValue = x/rct.Width();
y=log10(fValue);
It will work fine.
Any more question?
Agha Khan
|
|
|
|
|
Has anyone written any filters for directshow in Borland C++ builder 6? Specifically a Spectrum analyser or anything else that uses audio data from a file (not waveIn). I am writing a spectrum analyser filter and would appreciate some pointers!
|
|
|
|
|
This is rather interesting Could care a bit to explain how would one use this for example to detect DTFM tones with it? Seems like a nice idea that poped up in my head
|
|
|
|
|
This application is super!!!
|
|
|
|
|
I am having trouble writing audio spectrum analyzer. The output doesn't comes out right. I have the data: 16bits/Sample, Sampling Rate 44100Hz, Channels 2
what I am doing to get the data from Audio Buffer to my array (to be passed to FFT algorithm) is:
for (DWORD i=0,int j=0;j<(mBufferSize); i=i+2,j++)
{
buff = (short)AudioBuffer[i];
Buffer1[j] = buff;
}
Then I am passing the array (type: double) Buffer1 to FFT algorithm, written by Don Cross.
After that I calculate the magnitude of the frequencies that I need by using formula
magitude = sqrt(real[i]*real[i] + img[i]*img[i]);
The output just isn't coming out right, like winamp's & windows media player's spectrum analyzers? Does anyone knows how to do it, or link to a url etc that describes it.
Thanks a LOT in advance
Atif
|
|
|
|
|
Your code looks fine but remember that the magnitude of the frequency may need to be scaled before you can use it to render with. And the scaling factor you use changes the results of the spectrum. In my code I use magnitude/=256 to scale the output to something I can render.
As far as Winamp and Windows Media Player goes, The spectrum analyzer in windows media player does not display the same results as the default one in winamp. Secondly I tested two other spectrum analyzers in winamp and they display different results from each other. Both of which are totally different from the defualt spectrum analyzer. All four spectrum analyzers display different results than my sample application does.
One possible reason for this is that I use a 512 point FFT while Winamp uses a 576 point FFT. I do not know what point Windows Media Player uses but it is probably something different. This creates slightly altered views of the frequency spectrum. The second reason is scaling. You could scale using the mod, div, or xor functions each of which will create a different scaled view of the same spectrum. Which of these winamp uses, I am not sure. Finally the drawing code itself is different. For example my application uses the following to display the spectrum:
<br />
Rectangle(dc,0,0,rct.Width(),rct.Height());<br />
for (x = 1; x < rct.Width(); x ++)<br />
{<br />
y=log10(x/rct.Width());<br />
MoveToEx(dc,x,(y*rct.Height()+rct.Height()),NULL);<br />
LineTo(dc,x,(y*rct.Height() + rct.Height() - ((m_dArray[int((double(m_nLength)/double(rct.Width()))*x)]/(m_nMaxValue-m_nMinValue))*rct.Height())));<br />
}
Though I used to use:
<br />
Rectangle(dc,0,0,rct.Width(),rct.Height());<br />
for (x = 1; x < rct.Width(); x ++)<br />
{<br />
y=log10(x/rct.Width());<br />
MoveToEx(dc,x,(y*rct.Height()+rct.Height()),NULL);<br />
LineTo(dc,x,(y*rct.Height() + rct.Height() - m_dArray[int((double(m_nLength)/double(rct.Width()))*x)]));
}
while winamp's sample visualization uses:
<br />
Rectangle(memDC,0,0,576,256);<br />
for (y = 0; y < this_mod->nCh; y ++)<br />
{<br />
for (x = 0; x < 576; x ++)<br />
{<br />
MoveToEx(memDC,x,(y*256+256)>>(this_mod->nCh-1),NULL);<br />
LineTo(memDC,x,(y*256 + 256 - this_mod->spectrumData[y][x])>>(this_mod->nCh-1));<br />
}<br />
}
And the code for my EQ-style spectrum analyzer is:
<br />
dRangePerStep /= GetNumberOfSteps();<br />
for (WORD w = 0; w < nBars; w++)<br />
{<br />
stepRect.top = rct.bottom;<br />
int tot=0,nLargest=0;<br />
for (int i=pos; i<pos+nDiv; i++)<br />
{<br />
tot=tot+m_dArray[i];<br />
if (m_dArray[i] > nLargest)<br />
nLargest = m_dArray[i];<br />
}<br />
tot /= (m_nMaxValue-m_nMinValue);<br />
tot *= 2;<br />
TRACE("Total=%d Div=%d, Bars=%d dRange=%f Max=%d Min=%d Largest=%d\n",tot,nDiv,nBars,dRangePerStep,m_nMaxValue,m_nMinValue,nLargest);<br />
{<br />
stepRect.left = (rct.left+((xRight*(w+1))-xRight));<br />
stepRect.right = (xRight*(w+1));<br />
stepRect.bottom = stepRect.top;<br />
stepRect.top = rct.bottom - int(tot);<br />
CBrush br1;<br />
if (tot > m_nHighLevel)<br />
br1.CreateSolidBrush(GetHighColor());<br />
else if (tot > m_nMediumLevel)<br />
br1.CreateSolidBrush(GetMediumColor());<br />
else<br />
br1.CreateSolidBrush(GetLowColor());<br />
dc.FillRect(&stepRect,&br1);<br />
if (m_bGrid)<br />
dc.FrameRect(&stepRect,&br);<br />
<br />
stepRect.bottom = stepRect.top;<br />
stepRect.top = 0;<br />
}<br />
pos+=nDiv;<br />
}
I do not know what rendering algorthims the other three spectrum analyzers use (two from Winamp, and one from Windows Media Player). Anyways, I hope this helps you understand why you are getting different results using the same audio input, and why even Winamp does not agree with its own spectrum analyzers.
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!!!
|
|
|
|
|
Thanks a lot Aqiruse for the response. I am done with doing FFTs, the problem now I am having is scaling. I want my result to scale in a range of 0 - 100, and I have 16-bit audio (ranges from -32768 to 32767). The problem is that when I calculate magnitudes that resulting values at times reach 10004118, so how do I scale magnitude to 0 - 100?
Another problem is that the magnitudes for frequencies lower than 600Hz are considerably higher than those of higher frequencies, so when I scale all frequencies using same variable, what I get is very low (or almost 0) values for high frequencies and high values for lower frequencies? How do you suggest I fix this? Also, you said that I can use "mod", "div", "Xor" for scaling, Could you please also tell me, in a nutshell, how to do each?
Last thing is I read somewhere a formula for calculating dB of each frequency using its magnitude. I tried it but for some weired reason all values always came out almost the same, the formula is:
dB = 20 * log(magitude[i])
is this right? if not, DO you know the correct formula for that?
I would really appreciate if you answer my questions and thanks again for all the time & help
Best Regards,
Atif
|
|
|
|
|
Here are some actual sample magnitudes from sqrt(re*re+im*im)
53,323.000000000000
104,905.48173103588
203,852.32353837276
252,216.50864603600
730,519.91261426755
22,823.031608189605
5,065.2804702067961
365,776.75905055040
954,726.62992072559
1,031,940.7125378944
Using the Mod function to scale these values will give us (after converting to int):
53,323.000000000000 Mod 100 = 23
104,905.48173103588 Mod 100 = 5
203,852.32353837276 Mod 100 = 52
252,216.50864603600 Mod 100 = 16
730,519.91261426755 Mod 100 = 19
22,823.031608189605 Mod 100 = 23
5,065.2804702067961 Mod 100 = 65
365,776.75905055040 Mod 100 = 76
954,726.62992072559 Mod 100 = 26
1,031,940.7125378944 Mod 100 = 40
1024 is the FFT length
53,323.000000000000 Mod 1024 = 75
104,905.48173103588 Mod 1024 = 457
203,852.32353837276 Mod 1024 = 76
252,216.50864603600 Mod 1024 = 312
730,519.91261426755 Mod 1024 = 35
22,823.031608189605 Mod 1024 = 295
5,065.2804702067961 Mod 1024 = 969
365,776.75905055040 Mod 1024 = 208
954,726.62992072559 Mod 1024 = 358
1,031,940.7125378944 Mod 1024 = 772
Using the Div function to scale these values will give us (after converting to int):
53,323.000000000000 Div 100 = 533
104,905.48173103588 Div 100 = 1,049
203,852.32353837276 Div 100 = 2,038
252,216.50864603600 Div 100 = 2,522
730,519.91261426755 Div 100 = 7,305
22,823.031608189605 Div 100 = 228
5,065.2804702067961 Div 100 = 50
365,776.75905055040 Div 100 = 3,657
954,726.62992072559 Div 100 = 9,547
1,031,940.7125378944 Div 100 = 10,319
Using the XOR function to scale these values will give us (after converting to int):
53,323.000000000000 XOR 100 = 53,295
104,905.48173103588 XOR 100 = 104,877
203,852.32353837276 XOR 100 = 203,816
252,216.50864603600 XOR 100 = 252,252
730,519.91261426755 XOR 100 = 730,611
22,823.031608189605 XOR 100 = 22,851
5,065.2804702067961 XOR 100 = 5,037
365,776.75905055040 XOR 100 = 365,748
954,726.62992072559 XOR 100 = 954,626
1,031,940.7125378944 XOR 100 = 1,032,032
You can easily see the resulting differences in numbers depending upon whether you use mod, div, or xor. To scale between 0-100, perhaps the mod is what you want. Though I often see developers code using the div rather than mod. Of course the div will not limit results to the range of 0-100! Using the mod function, larger values will not necessarily result in large return values. For example (1,031,940 Mod 100 = 40) yet (5,065 Mod 100 = 65). While mod will certainly result in values being scaled to a certain range, it will not produce accurate results because larger values will not always result in large values being returned. Using the div function will always produce larger values for a large given value making it more accurate than mod, however, the returned values will not be scaled to a certain range. For this reason, most developers I have seen code from use the div function and clip the values to a certain range.
The magnitudes for bass frequencies will almost always be higher than the magnitudes for treble frequencies because bass frequencies take a lot of power to produce an audible note, while treble frequencies may produce the same note usine 1/10th the power. That is why cars will use a 200 Watt subwoofer, yet only use a 25 Watt treble speaker. As far as "correcting" this goes, I don't know other than to say I think it is how it is supposed to be.
I saw somewhere the following formulas for calculating decibles:
<br />
#define mag_sqrd(re,im) fabs(re*re+im*im)<br />
#define Decibels(re,im,nNumSamples) (10.0 * log10(double(mag_sqrd(re,im)/ double(nNumSamples))))<br />
#define Decibels(re,im) (20.0 * log10(double(mag_sqrd(re,im)))) // <br />
#define Decibels(pcm) (20.0 * log10(double(pcm)/65535.0f)) // Voltage formula for PCM samples ranging from 0-65535, etc. 16 bit range. For 24-32 bit range you change the 65535 to 16777215 or 4294967295 respectively.<br />
The 10 Log X[i] VI can convert magnitude squared or power values, such as acoustic pressure waves, to
decibels and the 20 Log X[i] VI can convert magnitude or amplitude values, such as voltages or currents, to
decibels.
Check out the following article on decibles: http://www.prorec.com/prorec/articles.nsf/articles/EA68A9018C905AFB8625675400514576
I am not sure which of these is the correct one to use for complex numbers though. Hope this helps answer some of your questions.
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!!!
|
|
|
|
|
Thanks a ton Lot Aqiruse. Your article & your answers have been very informative & helpful. I really appreciate the time you spent writing these answers. GOOD JOB!
Best Regards,
Atif Goheer
PS: You've got my 5!
|
|
|
|
|
could u give me example of how to pass buffer in array to ur fft? i duno how to do mine. i'm a newbie of vc++ 6. thx.
|
|
|
|
|
You need to stop the recorder before you program shuts down or you can run into access violations every once in awhile (I did) when the application is terminated. It is a race condition and will not happen all the time. The recorder thread was attempting to process the next buffer and the m_lpData pointer was already cleared out during a program shutdown and that caused an access violation. You should issue a m_rec.Stop() call prior to allowing the dialog box to shutdown. I simply made a cleanup method and implemented the OnOK and the OnCancel methods for the CDialog and had them do that.
|
|
|
|
|
Hi,
could anyone help getting this to compile with vc7.
....\source\Controls.h(11): fatal error C1083: Cannot open include file: 'strstrea.h': No such file or directory
the vc7 strstream is incompatible
Sorry, my heads fried with fft stuff and I cant get it working...
|
|
|
|
|
Did you by any chance cut-and-paste the compile error message into the post? If so, you just misspelled the file. It's missing the 'm' before the '.h'.
|
|
|
|
|
Let me take some remarks about the FFT, first is there are a lot of very good and efficient algorithm to calculating the FFT in place even in place and in order too. The second instead of two FFT you can use only one with the same length (N) and N extra step to get the final result.
darbal
|
|
|
|
|
Hi, I like your work, I'll try it today.
Can I use some of this in my projects?
And can yoy say more about audio compression, how to make it?
Are there any problems with 16Bit stereo audio, how you separate the channels before pasing them in FFT routine?
|
|
|
|
|
1) Can I use some of this in my projects?
yes feel free to use some of this in your projects. I just ask that you give credit where credit is due. So please make a note somewhere in the code you use, saying that you are using some of my code, or Don Cross's code.
2) And can yoy say more about audio compression, how to make it?
Well, this article was not really about audio compression. I was trying to show the usefulness of the FFT for audio applications.
3) Are there any problems with 16Bit stereo audio, how you separate the channels before pasing them in FFT routine?
If you wanted to seperate the audio, then you would merely make two seperate buffers, one for the left channel, another for the right channel, seperate the audio into the two buffers, then call the fft_double function twice, once for each channel. It is really not that difficult a task to do, though my code doesn't show it. Take a look at the updated code in the article, where I seperate the two channels. I have asked the webmaster to uploaded a new demo.zip for me, though I am not sure how long that will take. For now, the updated code is only in the article, not the demo....
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!!!
|
|
|
|
|
Great!!!
Best thanks, soon I'll contact you for more detiles.
I have already done some FFT, but using something working is beter.
Regards,
Georgi
|
|
|
|
|
Hi
I've downloaded the zip, but it doesn't contain an executable and I only have Visual studio standard version for C#.
I'd be grateful if you could include this, or perhaps email me one (win2000), but undertand if not possible.
Thanks
Gordon Moore
gmz@gordonmoore.me.uk
|
|
|
|
|
Have you tried to email me? I received some attempts, which were quarantined?
Gordon
|
|
|
|
|
Are there any specific requirements. When I run the application on WinXP I am getting nothing for display in all the modes.
It is great to see an article on this subject matter. Good Job.
|
|
|
|
|
Yes, you have to play some audio using another application first. While playing an audio file using RealPlayer or MusicMatch, then run the application and it will use the waveIn functions to display the results.
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!!!
|
|
|
|
|