views:

202

answers:

5

Hi, Im trying to do a screen-flashing application, that flashes the screen according to the music(which will be frequencies, such as healing frequencies, etc...). I already made the player and know how will I make the screen flash, but I need to make the screen flash super fast according to the music, for example if the music speeds up, the screen-flash will flash faster. I understand that I would achieve this by FFT or DSP(as I only need to know when the frequency raises from some Hz, lets say 20 to change the color, making the screen-flash).

But I've found that I understand NOTHING, even less try to implement it to my application.

Can somebody help me out to learn whichever both of them? My email is [email protected]. I really need help, I've been stucked for like 3 days not coding or doing anything at all, trying to understand, but I dont.

PS:My application is written in C++ and Qt.

PS:Thanks for taking the time to read this and the willingness to help.

Edit: Thanks to all for the answers, the problem is in no way solved yet, but I appreciate all the answers, I didnt thought I would get so many answers and info. Thanks to you all.

A: 

It sounds like maybe you're trying to get your visualizer to flash the screen in time with the music somehow. I don't think calculating the FFT is going to help you here. At any given instant, there will be many simultaneous frequency components, all over the audio spectrum (roughly 20 Hz to 20 kHz). But you're likely to be a lot more interested in the musical tempo (beats per minute -- more like 5 Hz or below), and that's not going to show up anywhere in an FFT of the raw audio signal.

You probably need something much simpler -- some sort of real-time peak detection. Whenever you see a peak greater than some threshold above the average volume, make your screen flash.

Of course, more complicated visualizations might well take advantage of the FFT, but not the one you're describing.

Jim Lewis
And how can I do the real-time peak detection?
Sismetic
@Sismetic: Please don't take this the wrong way, but I think you might need a basic audio processing tutorial, rather than a simple answer or code fragment that would be appropriate for Stack Overflow. bta posted some good links -- drill down from there, and you'll find some good information, though not necessarily in C++. What you're trying to do is kind of difficult for a beginner's programming project...good luck!
Jim Lewis
Thanks Jim, I know its kinda hard, but my dad left it, it's really my first project, like 3 months after starting learning C++, but im confident, this is the last problem I think Ill encounter, because I have all the rest worked out(apparently). Thanks for your answer, I appreciate it
Sismetic
+2  A: 

The output of a FFT will give you the frequency spectrum of an audio sample, but extracting the tempo from the FFT output is probably not the way you want to go.

One thing you can do is to use peak detection to identify the volume "spikes" that typically occur on the "down-beats" of the music. If you can identify the down-beats, then you can use a resource like bpmdatabase.com to find the tempo of the song. The tempo will tell you how fast to flash and the peaks you detected will tell you when to start flashing. Have your app monitor your flashes to make sure that they generally occur at the same time as a peak (if the two start to diverge, then the tempo may have changed mid-song).

That may sound straightforward, but this is actually a very non-trivial thing to implement. You might want to read this SO question for more information. There are some quality links in the answers there.

If I'm completely mis-interpreting what you are trying to do and you need to do FFTs for something different, then you might want to look at using one of the existing FFT libraries to do the heavy lifting for you. Some examples are FFTW and KissFFT.

bta
I foudn the FFTW library but I didnt understand squat :P, I only need to know when to flash the screen and need to flash the screen several times per second
Sismetic
@Sismetic- If that's all you are trying to do, then don't worry about FFTs. Take a look at some of the links in the other SO question I linked for some descriptions about how to approach the problem (the GameDev article in particular).
bta
@bta - I dont think beat detection as in BPM is what Im looking for, because it's not in music Ill be applying this,at least not normal music like Three Days Grace, Bon Jovi, or anthing like that. It's in like frequencies that are done digitally, and dont use bass, guitar or anything like that. It's like sound done at a really low frequency to induce you into a state(like sleepy, or active). It's hard to put in words, but I hope I expressed myself correctly
Sismetic
@Sismetic- If you are using pure-tone frequencies, then your job is really easy. The frequency of the sound is measured in cycles per second, and if you want to flash in time with the tone then you want to flash at that same rate. No calculations required. Note that the screen likely can't refresh faster than 60-72 Hz, so if your tone is higher pitched than that you will want to use some harmonic of that tone (divide the frequency by a power of 2 until you get a number within the screen's refresh rate).
bta
And how do I get the tone(programatically, I mean, because every different tone-frequency will play at different cycles per second, wouldnt it?) for each tone-frequency that will play(one at a time)Whats an harmonic?
Sismetic
I assumed you already knew what tones you would be using. How are you generating these tones without knowing their pitch or their frequency?
bta
Im not, my father is, the application is for me to perform on an already generated tone, and I guess I would have to get the frequency of the tone
Sismetic
Will your app always be using the same pre-generated tone(s), or will they be different each time? If you are re-using tones, it will be much easier to use an existing tool to measure their frequency and program the result into your app than it will be to code a pitch detector.
bta
They will be different every time. Do you know of a tool that measures the frequency? If you do, can you explain me how to use it on the app(I dont know how to use plug-ins or anthing at all, I have never done it)? Sorry for the untimely response :(
Sismetic
There is no easy way to explain how to do this in your app. I learned how to do it in a DSP course in college, but based on your admission I don't think you have the math background to do it right now. That's why I was trying to find a different way to approach the problem that wouldn't involve any DSP work. Try working through the book at dspguide.com and see if you have the math experience to make it through at least the "Foundations" and "Fundamentals" sections (13 chapters or so). If you can follow the math in that book, you should learn everything that you need to know.
bta
Ok, Im gonna try to read it online, as it looks to be of utter importance. I tried to print it, but it was by chapters, and I didnt thought it was very important, I was wrong. Thanks for all the help man
Sismetic
A: 

My recommendation would be to find a library that does this for you. Unless you have a lot of mathematics to back you up, I think you will be wasting a ton of your time trying to learn FFTs when all you really want out is some sort of 'base hits per minute' number out which you can adjust your graphics to accordingly.

Check out this similar post: here

It took me about three weeks to understand the mathematics behind FFTs and then another week to write something in Matlab using those concepts. If you are discouraged after three days, don't try and roll your own.

I hope this is helpful advice and not discouraging.

-Brian J. Stinar-

Brian Stinar
Can you give me a practical example on how to implement it?
Sismetic
If I were in your situation, I would start messing around with the "Vamp Plugin" system. From looking over this, it looks like they have a method which takes in an audio track and sampling methods as inputs, and returns to you (among other things) a tempo datastructure which includes the beats per minute, and some sort of timing mechanism to correlate tempo(s) to points of time in the audio track. However, I'm sorry I don't have a working example of this ready to go.
Brian Stinar
Thank you, Ill look into the Vamp Plugin
Sismetic
A: 

This is a difficult problem, requiring more than an FFT. I'll briefly describe how I implemented beat detection when I was writing software for professional DJ equipment.

First of all, you'll need to cut down the amount of data you're dealing with, since there are only two or three beats per second, but tens of thousands of samples. You'll also need to look at different frequency ranges, since some types of music carry the tempo in the bassline, and others in percussion or other instruments. So pass the signal through several band-pass filters (I chose 8 filters, each covering one octave, from low bass to high treble), and then downsample each band by averaging the power over a few hundred samples.

Every few seconds, you'll have a thousand or so samples in each band. Your next tool is an autocorrelation, to identify repetitive patterns in the music. The peaks of the autocorrelation tell you what the beat is more or less likely to be; but you'll need to make up some heuristics to compare all the frequency bands to find a beat that you can be confident in, and to avoid misleading syncopations. If you can manage that, then you'll have a reasonable guess at the tempo, but no idea of the phase (i.e. exactly when to flash the screen).

Now you can look at the a smoothed version of the audio data for peaks, some of which are likely to correspond to beats. Initially, look for the strongest peak over the course of a few seconds and take that as a downbeat. In conjunction with the tempo you estimated in the first stage, you can predict when the next beat is due, and measure where you actually saw something like a beat, and adjust your estimate to more closely match the data. You can also maintain a confidence level based on how well the predicted beats match the measured peaks; if that drops too low, then restart the beat detection from scratch.

There are a lot of fiddly details to this, and it took me some weeks to get it working nicely. It is a difficult problem.

Or for a simple visualisation effect, you could simply detect peaks and flash the screen for each one; it will probably look good enough.

Mike Seymour
And how do I detect the peaks?
Sismetic
@Sismetic: One simple way is to keep track of the average amplitude, and look for samples that are both considerably larger than average, and larger than all other samples within a smallish distance (say 100ms) of them. You might get better results by rectifying the signal (making negative samples positive), smoothing it (with a low-pass filter) and looking for attacks (sudden increases in amplitude), but that's more complicated.
Mike Seymour
And how do I get the samples?Sorry Im a REAL newbie
Sismetic
@Sismetic: sorry, I've no idea how to get at the audio stream; that entirely depends on what you're using to play the audio. You say you made the player - can you get the audio data out of that somehow?
Mike Seymour
I dont have a clue of how to do it
Sismetic
A: 

As previous answers have noted, an FFT is probably not the tool you need in order to solve your problem, which requires tempo detection rather than spectral analysis.

For an example of what can be done using FFT - and of how a particular FFT implementation was integrated into a Qt application, take a look at this blog post which describes the spectrum analyzer demo I developed. Code for the demo is shipped with Qt itself, in the demos/spectrum directory.

Gareth Stockwell
I saw it, and the red bars on the right are EXACTLY what I want, Im looking through the code to see how they did it :P Ty for the tip
Sismetic
The red bar on the right is rendered by the LevelMeter class. It displays two signals: the RMS signal level, with a small amount of smoothing applied; and the recent peak signal level, with a decay applied over time. Note that this signal will not give you an accurate measure of the beat tempo as it typically contains too much noise. You would need to do some more sophisticated processing, as pointed out in other responses, to detect the tempo of the music.
Gareth Stockwell
Oh thank you for telling me where to find that particular part. Thank you very much, yours was the most useful as far as today I found(although everyone's posts were very useful too).
Sismetic