migrating from fmod ex

  1. seems the fmod studio lowlevel api is quite similar, yet I wonder if there is some documentation about all api changes?

  2. it appears the lowlevel api (fmod[64].dll( is the 'new fmodex[.dll], yet I find it confusing regarding the original, obsolete fmod.dll. Anyway, using this new fmod dll, would it be ok to call it “FMOD [Studio] Soundsystem”?

  3. Is there any substitute for System_GetSpectrum?

  4. CD playback still does not work in 64bit (fmod64.dll from fmod studio) (FMOD_ERR_CDDA_INIT)

Sorry for the bump but figuring this out is somewhat time critical. I seem to use both fmod_vc.lib and fmodL_vc.lib in both the debug and release versions. All I can seem to find on the subject is that L is for logging/debugging purposes? Really confused atm. =S

What Brett was talking about regarding header / library mix up is the case where a developer uses headers for one version of FMOD with libraries from a different version. If the list of error codes has changed between two versions the library might return one error, but your incorrect headers say it is something different. Just make sure you are using the headers, libs and DLLs all from the same release of FMOD to avoid this problem.

As for which libs to use, we recommend you use fmod_vc.lib in your release version and fmodL_vc.lib for your debug version. The ‘L’ means logging, this will provide extra information on the TTY or fmod.log file about what FMOD is doing (which is useful for debugging).

Ohhhhhh, that makes A LOT more sense. I was so confused as to what I was doing wrong. xD

EDIT: Solve my own problem. =D

Alright so I’ve got the errors to go away, but I cannot for the life of me extract any useful data. I’m using VS2012, and when I try to debug and see what’s in data all I can see is the value 0.00000 (which it is initialized to). When I step through and check the values of the frequency array, those only meet the “else” condition, meaning instead of being == average / power it results in a 0.

Here’s the code I’m using (the other parts of the example code that Brett posted are initialized when I initialize my game’s audio manager.

    char s[256];
    unsigned int len;
    float *data = 0;
    float freq[32];

    result = dspfft->getParameterData(FMOD_DSP_FFT_SPECTRUM, (void **)&data, &len, s, 256);

	if (result != FMOD_OK)
	{
		std::cout << " FMOD !OK \n";
	}

    nyquist = windowsize / 2;

    for (int chan = 0; chan < 2; chan++)
    {
        float average = 0.0f;
        float power = 0.0f;

        for (int i = 0; i < nyquist-1; ++i)
        {
            float hz = i * (rate * 0.5f) / (nyquist-1);
			int index = i + (FLOAT_BETWEEN * chan);

            if (data[index] > 0.0001f)
            {
                average += data[index] * hz;
                power += data[index];
            }
        }

        if (power > 0.001f)
        {
            freq[chan] = average / power;
        }
		else
		{
			freq[chan] = 0;
		}
    }

did you actually add the dsp into the signal somewhere? Ie with addDSP?

Yeah, so I did in fact forget to do that (-_-`)…

Yeah I get actual data now, however I guess now is where things actually get tricky?

I’m hoping to do some “simple” beat detection using this, similar to what’s seen in this tutorial:
http://katyscode.wordpress.com/2013/01/16/cutting-your-teeth-on-fmod-part-4-frequency-analysis-graphic-equalizer-beat-detection-and-bpm-estimation/

I’m going to look into it right now, but since time is of the essence I thought I’d post the link to this, and see if an actual expert such as you wonderful Firelight employees could help me out by guiding me down the right path?

Thanks!

beat detection is a pretty big topic, i’ve tried it myself once and it was pretty rudimentary and i scrapped it - i think the link you gave is a lot more researched than anything we have in our back pocket :slight_smile:

Hi ,
for your questions

  1. yes there is a page in the documentation with differences between fmodex and fmod studio low level.
  2. what are you asking to call? FMOD Studio is the name of the product, i’m not sure where you want to put that.
  3. yes, add a FMOD_DSP_TYPE_FFT dsp, and you can use getParameter to get the old info, including a new float called ‘dominant frequency’.
  4. we’re removing CDDA support in the next release of FMOD Studio (though its still in 1.2), its time to move on from this old format.

Yeah I’m unable to get any useful data either.

Does anyone else have any experience with this? :-?

So, as a total noob who’s not sure which getParameter function I should be using, nor how to properly use any of the said functions, could some sample code perhaps be posted of how to do something basic that is similar in functionality to getSpectrum from FMOD EX?

Also, sorry for bumping an old thread.

Thanks!

poked around a bit, but seems pretty undocumented for some reason.

I assume this should give some infos for a trial and error attempt:
typedef enum
{
FMOD_DSP_FFT_WINDOWSIZE, /* (Type:int) - [r/w] Must be a power of 2 between 128 and 16384. 128, 256, 512, 1024, 2048, 4096, 8192, 16384 are accepted. Default = 2048. /
FMOD_DSP_FFT_WINDOWTYPE, /
(Type:int) - [r/w] Refer to FMOD_DSP_FFT_WINDOW enumeration. Default = FMOD_DSP_FFT_WINDOW_HAMMING. /
FMOD_DSP_FFT_SPECTRUM, /
(Type:data) - [r] Returns the current spectrum values between 0 and 1 for each ‘fft bin’. Divide the niquist rate by the window size to get the hz value per entry. /
FMOD_DSP_FFT_DOMINANT_FREQ /
(Type:float) - [r] Returns the dominant frequencies for each channel. */
} FMOD_DSP_FFT;

This should be the 4 parameters the fft dsp has, and how to use.

I guess my only remaining question now that I have this information is about the function DSP::getParameterData(). I get that index is the index I want to get the data from in the DSP type, and that data is where the data is essentially written, but length - what is length referring to? And can I set valuestr, and valuestrlen to NULL?

Thanks again!

played around a bit myself, but couldn’t get FMOD_DSP_SetParameterInt with #FMOD_DSP_FFT_WINDOWSIZE and #FMOD_DSP_FFT_WINDOWTYPE to work at all.

FMOD_DSP_GetParameterData with FMOD_DSP_FFT_SPECTRUM seems to return sucessfull / without crash, but I get no spectrum data so far. Also don’t know how to specify which channel (left/right) to get the spectrum from.

for the length parameter, I assume it is some kind of (optional) pointer.
for valuestr and valuestrlen passing 0 seems to work (its not stated optional in the documentation, so I’d recommend specifying (valuestr as pointer to 16 bytes of memory, valuestrlen 16), however, I wonder why the valuestrlen is relevant if there is a 16 byte limit.
it should return some (ansi?) text to the memory specified in valuestr, but does not.

Hi ,
The FMOD_DSP_TYPE_FFT effect is a bit underdeveloped/documented compared to the rest of the effects. Hopefully I can clear up some confusion (i’m also in the process of updating the documentation for it, and changing the ‘data’ to a struct so you can get a bit more info out of it).

Firstly the valuestr/valuestrlen is unused right now because there’s no real way to make a string out of something that’s not a scalar value - so i’ve updated it to just return the string “spectrum data” for the next release.

Next, “length” of data is how many floats there are. This is window size * channels in signal. 1024 window size in a stereo dsp chain, should return 2048 for example as length.
As for the spectrum, it contains float data for each channel, up to window_size values.

Just debugging now - it looks like each channel is 16384 floats apart from each other.
so in a 2 channel signal,

left = data + 0 = first ‘window_size’ # of floats. then right = data+16384 = next window_size of floats. Every 16384 floats there are more channels (ie up to 32 channels).
This is a lot of memory (2mb) which took me by surprise so i might reduce that somewhat in the next release.

When I debugged it the values came through ok. I tested on a sine wave using a triangle window (triangles are really only good for periodic tones like sine waves btw).

Note the data only starts coming through when a signal is heard, not when the signal path is idle.

Here is code that works under the current release

   if (dspfft)
        {
            float val;
            char s[256];
            unsigned int len;
            float *data = 0;
            float freq[32];
            int rate, chan,nyquist;
            int windowsize = 4096;

            result = gSystem->getSoftwareFormat(&rate , 0, 0);
            ERRCHECK(result);

            result = dspfft->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_TRIANGLE);
            ERRCHECK(result);

            result = dspfft->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, windowsize);
            ERRCHECK(result);

            result = dspfft->getParameterFloat(FMOD_DSP_FFT_DOMINANT_FREQ, &val, 0, 0);
            ERRCHECK(result);

            result = dspfft->getParameterData(FMOD_DSP_FFT_SPECTRUM, (void **)&data, &len, s, 256);
            ERRCHECK(result);

            nyquist = windowsize / 2;

            for (chan = 0; chan < 2; chan++)
            {
                float average = 0.0f;
                float power = 0.0f;

                for (int i = 0; i < nyquist-1; ++i)
                {
                    float hz = i * (rate * 0.5f) / (nyquist-1);
                    int index = i + (16384 * chan);

                    if (data[index] > 0.0001f) // aritrary cutoff to filter out noise
                    {
                        average += data[index] * hz;
                        power += data[index];
                    }
                }

                if (power > 0.001f)
                {
                    freq[chan] = average / power;
                }
                else
                {
                    freq[chan] = 0;
                }
            }
            printf("\ndom freq = %d : %.02f %.02f\n", (int)val, freq[0], freq[1]);
        }

The next release will have this structure as the FFT Spectrum parameter.

/*
[STRUCTURE] 
[
    [DESCRIPTION]
    Structure for data parameters of type FMOD_DSP_PARAMETER_DATA_TYPE_FFT.
    A parameter of this type is declared for the FMOD_DSP_TYPE_FFT effect.

    [REMARKS]
    Members marked with [r] mean the variable is modified by FMOD and is for reading purposes only.  Do not change this value.<br>
    Members marked with [w] mean the variable can be written to.  The user can set the value.<br>
    <br>
    Notes on the spectrum data member.  Values inside the float buffer are typically between 0 and 1.0.<br>
    Each top level array represents one PCM channel of data.<br>
    Address data as spectrum[channel][bin].  A bin is 1 fft window entry.<br>
    Only read/display half of the buffer typically for analysis as the 2nd half is usually the same data reversed due to the nature of the way FFT works.<br>

    [SEE_ALSO]    
    FMOD_DSP_PARAMETER_DATA_TYPE
    FMOD_DSP_PARAMETER_DESC
    FMOD_DSP_PARAMETER_DATA_TYPE_FFT
    FMOD_DSP_TYPE
    FMOD_DSP_FFT
]
*/
typedef struct FMOD_DSP_PARAMETER_FFT
{
    int     length;                                    /* [r] Number of entries in this spectrum window.   Divide this by the output rate to get the hz per entry. */
    int     numchannels;                               /* [r] Number of channels in spectrum. */
    float  *spectrum[32];                              /* [r] Per channel spectrum arrays.  See remarks for more. */
} FMOD_DSP_PARAMETER_FFT;

The main differences - no more reference to 16384, use spectrum[channe][bin]. Numchannels is provided. It is a bit of guess work with the current release. Generally if it is a channelgroup with multiple signals coming into it, it will be numchannels = the number of channels in the mixer. On a channel, it would be the number of channels in the source sound. (ie a stereo sound is 2).

Can you tell us more about this Structure and how can we get the spectrum Data from this?? I tried to modify your example in the first page with this structrure and my vector is always getting the same values :S

Ok so you used System::createDSPByType and used FMOD_DSP_TYPE_FFT, and then where did you put it? It is probably where you put it which is the issue? Try System::getMasterChannelGroup, then ChannelGroup::addDSP(FMOD_CHANNELCONTROL_DSP_HEAD, …), and make sure you call System::update regularly. If you can hear sound, then the spectrum array should fill with data that changes.

Okay, now I’m encountering a different error using the code you provided (just to see what happens, didn’t really expect it to magically work) in my code, with name changes so it would fit. Basically when I do the getParamtereData() result is equal to FMOD_ERR_MAXAUDIBLE. I looked in the documentation and noticed it said that it means I’ve surpassed the max playback count from the soundgroup in question - but I haven’t defined any soundgroups? So do I need to or can something else cause this error? And what benefit is there in using soundgroups exactly?