irrKlang function to get spectrum

Discussion about everything. New games, 3d math, development tips...
Post Reply
kazymjir
Posts: 727
Joined: Sat Feb 20, 2010 4:05 pm
Location: Munich, Bayern

irrKlang function to get spectrum

Post by kazymjir »

Hello !

Some time ago I was writing and testing some code for my game.
I needed to make a waving camera to the sound that is playing.
Everything is good, you can watch results here:
http://w968.wrzuta.pl/film/8klEeIeEbOq/szatan
http://w829.wrzuta.pl/film/2upysN8r4Hl/ ... 002_i_chuj
(camera is waving some in same ways, but I will repair it).

The problem is, that library that I used (FMOD) have one problem in Windows.
I can't use C++ interface, because linker throwing tons of undefined references.
I googled some and found that this is impossible to compile under mingw,
so there is two ways to fix this problem: use C interface or use other compilator.

I know only msvc on windows, but my game will be released as FreeSoftware, so I don't want use any propertiary tools.

Now I want to use irrKlang, but I don't know how to get sound spectrum.
Do you know how can I do that?
At google I found nothing.

In my version I am using getSpectrum function, taking from it amplification of low frequencies and doing some arithmetics to use it to setPosition of cam.

There is FMOD function to do this, I need something similar:
Firelight Technologies FMOD Ex
System::getSpectrum

Retrieves the spectrum from the currently playing output signal.

C++ Syntax

FMOD_RESULT System::getSpectrum(
float * spectrumarray,
int numvalues,
int channeloffset,
FMOD_DSP_FFT_WINDOW windowtype
);

C Syntax

FMOD_RESULT FMOD_System_GetSpectrum(
FMOD_SYSTEM * system,
float * spectrumarray,
int numvalues,
int channeloffset,
FMOD_DSP_FFT_WINDOW windowtype
);

Parameters

spectrumarray
Address of a variable that receives the spectrum data. This is an array of floating point values. Data will range is 0.0 to 1.0. Decibels = 10.0f * (float)log10(val) * 2.0f; See remarks for what the data represents.

numvalues
Size of array in floating point values being passed to the function. Must be a power of 2. (ie 128/256/512 etc). Min = 64. Max = 8192.

channeloffset
Channel of the signal to analyze. If the signal is multichannel (such as a stereo output), then this value represents which channel to analyze. On a stereo signal 0 = left, 1 = right.

windowtype
"Pre-FFT" window method. This filters the PCM data before entering the spectrum analyzer to reduce transient frequency error for more accurate results. See FMOD_DSP_FFT_WINDOW for different types of fft window techniques possible and for a more detailed explanation.

(...)

Remarks

The larger the numvalues, the more CPU the FFT will take. Choose the right value to trade off between accuracy / speed.
The larger the numvalues, the more 'lag' the spectrum will seem to inherit. This is because the FFT window size stretches the analysis back in time to what was already played. For example if the window size happened to be 44100 and the output rate was 44100 it would be analyzing the past second of data, and giving you the average spectrum over that time period.
If you are not displaying the result in dB, then the data may seem smaller than it should be. To display it you may want to normalize the data - that is, find the maximum value in the resulting spectrum, and scale all values in the array by 1 / max. (ie if the max was 0.5f, then it would become 1).
To get the spectrum for both channels of a stereo signal, call this function twice, once with channeloffset = 0, and again with channeloffset = 1. Then add the spectrums together and divide by 2 to get the average spectrum for both channels.

What the data represents.
To work out what each entry in the array represents, use this formula

entry_hz = (output_rate / 2) / numvalues

The array represents amplitudes of each frequency band from 0hz to the nyquist rate. The nyquist rate is equal to the output rate divided by 2.
For example when FMOD is set to 44100hz output, the range of represented frequencies will be 0hz to 22049hz, a total of 22050hz represented.
If in the same example, 1024 was passed to this function as the numvalues, each entry's contribution would be as follows.

entry_hz = (44100 / 2) / 1024
entry_hz = 21.53 hz
Thanks in advice!


PS: if somebody want source code or map from video, just say it here and i will upload somewhere
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

There is a special dedicated irrKlang forum over at ambiera.com. I guess you'll get more help there.
Post Reply