Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dsp::get_parameter_data usage for getting the FFT spectrum of a channel #5

Closed
fililip opened this issue Aug 30, 2022 · 4 comments
Closed
Labels
enhancement New feature or request

Comments

@fililip
Copy link

fililip commented Aug 30, 2022

There doesn't seem to be an easy way of accessing FFT spectrum information of a channel.

Dereferencing pointers to libfmod::ffi::FMOD_DSP_PARAMETER_FFT after receiving them via calls to Dsp::get_parameter_data() in unsafe blocks doesn't sound like the best idea (it doesn't even return any data anyway, which renders the whole procedure useless), while the FFT DSP feature of FMOD is one that does come in handy and should, in my opinion, be properly implemented as part of the binding.

Is there something that could be done here to fix this?

@lebedec
Copy link
Owner

lebedec commented Aug 31, 2022

I think this can be improved.

There are two ways:

  • Add a new abstraction layer, another wrapper to implement special cases like this manually.
  • Improve a generator. Although the library is fully generated, I made a some preparations that allow to override the generation results.

The first way is huge solution decision, now it impossible. But, I can try improve generator to eliminate unsafe blocks and deref pointers in wrapper.

It will help a lot If you send me code examples where FMOD_DSP_PARAMETER_FFT parameter is used (any C/C++ code possible) or write your vision of Dsp::get_parameter_data() function signature and usage for example.

@fililip
Copy link
Author

fililip commented Aug 31, 2022

Here's a code snippet from my audio player written in C# (I used the official FMOD binding for C#):

IntPtr fftData;
uint fftLength;

fftDSP.getParameterData((int)DSP_FFT.SPECTRUMDATA, out fftData, out fftLength);

DSP_PARAMETER_FFT fft = (DSP_PARAMETER_FFT)Marshal.PtrToStructure(fftData, typeof(DSP_PARAMETER_FFT));
fft.getSpectrum(ref spectrum);

if (fft.numchannels > 0)
{
  for (int i = 0; i < values.GetLength(1); i++)
  {
    ...

IntPtr is the "safe" pointer type in C#.
The DSP_PARAMTER_FFT.getSpectum() function in the C# binding returns the .spectrum parameter of the structure (float[][]).

The same thing applies to C/C++: you call getParameterData() with a pointer to an instance of that structure cast to void** to get your FFT data, so something along the lines of:

FMOD_DSP_PARAMETER_FFT *fft;
fftdsp->getParameterData(FMOD_DSP_FFT_SPECTRUMDATA, (void **)&fft, 0, 0, 0));
for (int channel = 0; channel < fft->numchannels; channels++)
{
    for (int bin = 0; bin < fft->length; bin++)
    {
        float val = fft->spectrum[channel][bin];
    }
}

Hope that clears things up!

@lebedec
Copy link
Owner

lebedec commented Aug 31, 2022

Thanks, I'll try to fix it.

@lebedec lebedec added the enhancement New feature or request label Aug 31, 2022
@lebedec
Copy link
Owner

lebedec commented Sep 3, 2022

The problem more difficult than I thought because of design FMOD_DSP_GetParameterData.
This function too generic and used not only for any DSP type but for any user defined data.
Also FMOD do not provide any typing info for safe pointer casting.

So, there is no ease way to handle *c_void. I have no idea how to implement this without reworking high level design of library.

But I implemented TryFrom trait specific for DspParameterFft to simplify safe usage. Hope that it helps you:

let sound = system.create_sound("./data/beep.wav", FMOD_DEFAULT, None)?;
let channel = system.play_sound(sound, None, false)?;
let dsp = system.create_dsp_by_type(DspType::Fft)?;
channel.add_dsp(0, dsp)?;
while channel.is_playing()? {
    // do something
}
let fft = DspParameterFft::try_from(dsp)?;
for channel in fft.spectrum.iter() {
    let sum: f32 = channel.iter().sum();
    println!("length: {}, sum: {}", fft.length, sum);
}

@lebedec lebedec closed this as completed Sep 3, 2022
@lebedec lebedec transferred this issue from another repository May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants