0
0

Hi,

i am playing around with the latest alpha release of fmodex. Actually, i am stuck on the dsp functions. Unfortunately there is no example right now because I just wanted to know how to do DSP in the fmodex-way? I found the creation of some DSP function but where is the actual callback registration? I am looking for a dsp callback that’s called for some amount of pcm-data and a second dsp-callback that actually creates data. The first one could be a echo effect and the second one is for example a signal generator. I know there is a brand new oszillator in fmodex, but I believe there is second way to do this :) I think I am blind, but could you give me a hint?

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

Thank you for the tip. I found a better solution for my first problem (streamsplitter) and now I wanted to install a DSP handler for some actual dsp-code. I wrote a dummy dsp for testing pusposes and I assume it should play no sound since I don’t write something to the output pin.

[code:32nidg4t]
FMOD_RESULT F_CALLBACK dsp_actual_reader(FMOD_DSP *dsp, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels)
{
return FMOD_OK;
}

FMOD_RESULT F_CALLBACK dsp_reset(FMOD_DSP *dsp)
{
return FMOD_OK;
}

strcpy(description.name,"DSPCODE"); /* [in] Name of the unit to be displayed in the network. /
description.version = 1; /
[in] Plugin writer’s version number. /
description.channels = 0; /
[in] Number of channels. Use 0 to process whatever number of channels is currently in the network. >0 would be mostly used if the unit is a unit that only generates sound. /
description.create = 0; /
[in] Create callback. This is called when DSP unit is created. Can be null. /
description.release = 0; /
[in] Release callback. This is called just before the unit is freed so the user can do any cleanup needed for the unit. Can be null. /
description.reset = dsp_reset; /
[in] Reset callback. This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state. Use to avoid clicks or artifacts. /
description.read = dsp_actual_reader; /
[in] Read callback. Processing is done here. Can be null. /
description.setposition = 0; /
[in] Set position callback. This is called if the unit wants to update its position info but not process data, or reset a cursor position internally if it is reading data from a certain source. Can be null. */

description.numparameters   =   0;      /* [in] Number of parameters used in this filter.  The user finds this with DSP::getNumParameters */

FMOD_DSP_PARAMETERDESC parameterdesc;
parameterdesc.min       =   0;                                /* [in] Minimum value of the parameter (ie 100.0). */
parameterdesc.max       =   255;                                /* [in] Maximum value of the parameter (ie 22050.0). */
parameterdesc.defaultval    =   100;                         /* [in] Default value of parameter. */
strcpy(parameterdesc.name,"test");                           /* [in] Name of the parameter to be displayed (ie "Cutoff frequency"). */
strcpy(parameterdesc.label,"einheit");                          /* [in] Short string to be put next to value to denote the unit type (ie "hz"). */
parameterdesc.description   =   "Streamsplitter";

description.paramdesc   =   &parameterdesc;          /* [in] Variable number of parameter structures. */
description.setparameter    =   0;       /* [in] This is called when the user calls DSP::setParameter.  Can be null. */
description.getparameter    =   0;       /* [in] This is called when the user calls DSP::getParameter.  Can be null. */
description.config      =   0;             /* [in] This is called when the user calls DSP::showConfigDialog.  Can be used to display a dialog to configure the filter.  Can be null. */
description.configwidth =   0;        /* [in] Width of config dialog graphic if there is one.  0 otherwise.*/
description.configheight    =   0;

result =systemSilent->createDSP(&description, &dsp);
ERRCHECK(result);

result = systemSilent->playSound(FMOD_CHANNEL_FREE, soundOrg, true, &channelSilent);
ERRCHECK(result);

result = channelSilent->addDSP(dsp);

[/code:32nidg4t]

This code crashes directely in addDSP. Did I do something wrong or it is a bug?

Thanx
Matthias

  • You must to post comments
0
0

Hi brett,

actually, I don’t need a parameter for this partiular DSP-function. If I understand your concept in the right was it will only harm anything when I will do setParameter or getParameter and it’s only passed through, so it shouldn’t do anything bad.

bye
Matthias

  • You must to post comments
0
0

Hi again,

I just had a new question. Is there a way to do some playback right a way from a memory location? That means I fill my buffer (e.g. 5 MB) with PCM data. Could fmodex play right from there or is it neccessary to start up a DSP?

cheers
Matthias

  • You must to post comments
0
0

Hi brett,

thank you for your answer. I do have an additional question. If I want to play a stream from memory is there any chance to avoid the length parameter as sugusted in FMOD_CREATESOUNDEXINFO ? Is there another way to create a user defined stream as through your given procedure (FMOD_OPENMEMORY)? Maybe something like a Oszillator DSP but with user defined buffers?

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

thanks, for your reply I didn’t see this example 😉 It’s exactly what I want.
I’ll try to do streaming to two soundcards today. I’ll first copy the playing buffer from the one input stream through a DSP and play it on a generating DSP on two soundcards. Is this the intended procedure for this application?

best regards
Matthias

  • You must to post comments
0
0

Hi,

I got my dual output working. Now I am on the way to make it more reliable for my use in our program. That means to encapsulate in classes and to do all this splitting in a backendend class. Therefore I tried to pass a structure into the

[code:9q4vmj8z]FMOD_RESULT F_CALLBACK pcmreadcallback(FMOD_SOUND *sound, void *data, unsigned int datalen)[/code:9q4vmj8z]

function so I put a UserData filed in the Sound -Object that is previously created by createSound and all the extended stuff.

In pcmreadcallback I do something like that:
[code:9q4vmj8z]
FMOD::Sound * fsound = (FMOD::Sound *)sound;
void * bp;

if(fsound)
{
result = fsound->getUserData(&bp);
    ... here bp is NULL ...
}

[/code:9q4vmj8z]

Is that a bug or am I missing something? I read the callback-Thread and there was said that the FMOD_CHANNEL is not equal to FMOD::Channel but one may cast them. So I assume it’s the same here. I did some address comparision and found that the sound parameter in the callback is mostly 0x1D0 different to the original sound-pointer. I couldn’t find a structure with this size yet.

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

thank you for your answer. I think I have to clarify thing a bit more :)
First I am creating a USER-Stream with CreateSound and the CREATESOUNDEX-Structure where I specify the pcmreadcallback – so I get a new Sound * Pointer. Then I am using the Sound::setUserData function to specify a pointer to my own user data. Now I expect to get the UserData back via Sound::getUserData inside the callback from the FMOD_SOUND structure. In other words is the sound * in pcmcallback equal to the sound * created by system->createSound ? If not how do I make a callback-call unique? That means, I need external buffers from my own objects.
Hopefully, I didn’t miss anything …

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

Yes I noticed that the callback was called while the stream was opened. Prebuffering?
So, I probably will have to wait for the next beta until I can go ahead with my implementation. If you have a testversion I would appreciate if you could send it to me :)

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

I got your new fmod working with my stream-splitting-code :) And it works perfectely. Actually, since I use readData on a Sound that is not playing to do the splitting I can’t do getPosition and I can’t setPosition :( I wrote some code to calculate the current position from the read data but for setPosition I think I don’t have any chance to do that. I assume I will have to play this channel silently and catch the pcm-data from a playing stream. Do you have any other advise how to do that? In other words is there a way to read the data from a channel like Channel::readData? That would be great since that would be the calculated data that’s gone through the DSP-chain.

cheers
Matthias

  • You must to post comments
0
0

hi brett,

thank you for your reply.
I am not sure how to do that since the FMOD_DSP_DESCRIPTION::read callback is defined with float* buffers as in and output. Which range is it here -1.0 till 1.0? Is that there a good method to recalculate PCM-Data from these values? I assume I will have to shift all values to DWORD. It’s pretty time consuming I think. Then I will save the buffer in small portions and I will play them from a user defined sound. Do you have any other suggestions?

best regards
Matthias

  • You must to post comments
0
0

Hi brett,

I just found the getWaveData function in Channel but it’s float* too. Actually, is there any possibility to get PCM-Data from the Channel?

Thanx
Matthias

  • You must to post comments
Showing 11 results
Your Answer

Please first to submit.