0
0

I’m building an MFC application in Visual C++ with FMOD providing the sound playback capabilities. I’ve created a very rudimentary drum machine. The machine has a bank of 16 sample slots. The user can assign a small wave “one-shot” file to each slot (behind the scenes I take the PCM data from the wave file and use FMOD’s sample upload function to convert it into a FMOD_Sample). The user can also assign a desired bpm and then designate at what point in a simple 1 bar loop any of the sounds must be triggered (I am letting the user plot points at every 1/16th interval).

The problem is when the user presses the “Play” button, I need a way of making the samples play simeltaneously (they may be incident at the same point) and with very good timing. Right now, I’m calculating the time increment from one 16th to the next in milliseconds and am using the MFC’s SetTimer function. This isn’t very good – the tempo seems to be vary depending on what the CPU is doing at the time, unlike commercial applications such as Reason where it does not variate at all.

Does FMOD have any tempo pulse generating facility at all?

  • You must to post comments
0
0

[quote="brett":20s5l4j2]If you use software sounds and play them from an FMOD dsp callback they will all start simultenously without variation.
The dsp callback occurs in the same thread as the mixer, so if you call playsound there, the next step will be to play mix them, so it will be perfectly aligned.[/quote:20s5l4j2]

so I simply write my own DSP callback and play them from there?

i was looking at one of the examples, I read this line of code in the main.cpp file for /dsp folder

[code:20s5l4j2]
FSOUND_PlaySoundEx(FSOUND_FREE, samp1, DrySFXUnit, FALSE);
[/code:20s5l4j2]

let me see if i understand whats happening; samp1 is being played [i:20s5l4j2]via[/i:20s5l4j2] the DSP unit DrySFXUnit?

So say if I had samples named samp1 upto sampN. If I wanted to play them all, perfectly, aligned, could I just do

[code:20s5l4j2]
FSOUND_PlaySoundEx(FSOUND_FREE, samp1, DrySFXUnit, FALSE);
FSOUND_PlaySoundEx(FSOUND_FREE, samp2, DrySFXUnit, FALSE);
//....
FSOUND_PlaySoundEx(FSOUND_FREE, sampN, DrySFXUnit, FALSE);
[/code:20s5l4j2]
pardon my ignorance, i’m sure with a little assistance i’ll be able to work it out

  • You must to post comments
0
0

ok i fully understand you now, thanks…however i’m getting some strange problems…these are probably specific to Visual C++ but I’ll mention them here anyhow.

in one of my classes I have a private static function like
[code:p5ckthpk]
void *callback ( void *originalbuffer, void *newbuffer, int length, void *userdata);
[/code:p5ckthpk]
in the .cpp implementation file of that class, one of the methods contains the code
[code:p5ckthpk]
FSOUND_DSP_Create(&callback, 0, 0);
[/code:p5ckthpk]
Visual C++ comes up with the following compilation error
[code:p5ckthpk]
c:\3rd year project\code\sditest2\sequencer.cpp(285) : error C2664: ‘FSOUND_DSP_Create’ : cannot convert parameter 1 from ‘void *(void *,void *,int,void *)’ to ‘void *(__stdcall *)(void *,void *,int,void *)’
None of the functions with this name in scope match the target type
[/code:p5ckthpk]
If I remove the ampersand and try
[code:p5ckthpk]
FSOUND_DSP_Create(callback, 0, 0); //removed ampersand before callback
[/code:p5ckthpk]
I still get the same error.

  • You must to post comments
0
0

[quote="brett":dnejs8ux]hi,
you havent declared your callback as FMOD has it defined.

[code:dnejs8ux]
typedef void * (F_CALLBACKAPI *FSOUND_DSPCALLBACK) (void *originalbuffer, void *newbuffer, int length, void *userdata);
[/code:dnejs8ux]

so make it void * F_CALLBACKAPI callback(etc..[/quote:dnejs8ux]

it didn’t like that either but i did

void* __stdcall callback and that worked. i have a feeling that it isn’t correct but i compiled and it worked.

brett, i have a few more queries about the dsp units. if i only make 1 dsp unit active, does its output buffer feedback into it as an input buffer?

oh and 1 more thing – the solution you suggested is working brilliant however if i need to trigger the sounds ever, say, 187.5 ms, the best I can do is wait until the callback is called 8 times (because 7.5 * 25 = 187.5)…i don’t suppose i could change the time lapse from 25ms to something else?

  • You must to post comments
0
0

i see. do you have any suggestions on how i can achieve an arbitrary time between each time i trigger the samples?

i wanted to do something like

[code:1m4syb91]
while ( 1 )
{
wait(N milliseconds);
do { PlaySound etc... }
}
[/code:1m4syb91]

any ideas at all would be extremely helpful.

thanks.

  • You must to post comments
0
0

[quote="brett":cg1vdv35]using sleep or gettime etc is not very accurate, but if you dont mind it then i would just suggest setting up a thread that plays a note then sleeps for the desired interval to the next note. Use FSOUND_HW2D and you should get better latency, and remove the fmod mixer granularity from the equation.[/quote:cg1vdv35]

great. thanks. i’ve just found out about multimedia timers and i’ve implemented one. seems to be working ok (i’ve lost the perfect alignment i got from the callback but i suppose i can just pre-mix the samples myself into one).

  • You must to post comments
Showing 5 results
Your Answer

Please first to submit.