0
0

Hello,

I am using FMOD to make a little live synth app. When the user releases a button, I stop the associated pitch or sound sample. This causes an audible click when using an ocilator, but seemingly not with a wave. I guess the wave is automatically smoothing out the end when I turn it off? Is there an easy way to make the ocilator DSP node do that, too?

An alternative solution to the "smoothing" above would be some way of telling FMOD that when I turn of the ocilator/sound, I want it to wait until the next time the waveform crosses zero to truly stop playback.

I would think many FMOD programmers have solved this problem many times and would love to hear the best ways.

Thank you.

  • You must to post comments
0
0

hm i guess you could add your own little dsp unit that does a ramp, but another way is to call setVolume(0) on the channel or setInputMix(0) so fmod’s mixer ramps it for you, then wait about 10ms then call stop or whatever you do.

  • You must to post comments
0
0

I see…

So I could call setVolume(0), setDelay(10ms), and stop() all in the same function, and it should ramp the volume down nicely before stopping without me having to make any other function calls later. I will have to try that. Thanks.

-Bill

  • You must to post comments
0
0

Didn’t work.

Why doesn’t setDelay() seem to do what I thought in this case? Am I thinking it should do something that it shouldn’t?

  • You must to post comments
0
0

I said sleep, (or just wait a few frames) so why are you calling setDelay? I didn’t say to use that function at all (if by setdelay you mean fmod’s function).

  • You must to post comments
0
0

By the way Brett, thanks for your continued attention to this. I am very appreciative of your comments.

You are exactly correct. It was my idea to use SetDelay, which doesn’t matter too much because it doesn’t appear to do what I thought (I thought it would wait x number of msec in the background before calling channel::stop(), while I could meanwhile let my program continue to run ) I decided to try using setDelay because I thought the code would have looked much cleaner then what I will try next (see below). It doesn’t matter too much since I still would have had to delete the ocillator DSP node after calling channel::stop(), and SetDelay() definetly won’t do that for me. Though now that I write that out, I realize that perhaps I should be creating a set number of ocillator DSP nodes at initialization, and not creating and destroying them as notes are played. Would that have a significant effect on latency, do you think?

Now that you mention sleep() specifically, thanks for the suggestion. I am not sure I want that, because I don’t want my program to just sit there for 10 ms while I wait for the ramping to happen from my call to Channel::SetVolume(0). This would mean that if someone simultaneously released a chord of 5 notes, there is all of a sudden a 50 msec latency! also, as the number of notes being released increases, eventually there would be a perceptible difference in time; In other words: the last note could be turned off much later then the first note, when they are all supposed to go off at the same time.

Your suggestion of waiting a few frames sounds very good. Unfortunately, waiting a few frames may not be an option. My synth module is abstracted away from anything having to do with the video, as all the OOP lovers would suggest. I suppose I could add an update() function to my synth module, but I think the drawing code is in a separate thread, so it may not work. If I stick with a single threaded app, this is probably a very sensible choice, but I am not sure about that right now. For games it would probably make a lot of sense.

Another suggestion could be to use timer callbacks from some other library; after I set volume to 0, I call a timer. the timer waits ~10msec or whatever appropriate, and then calls another one of my functions which calls channel::stop() and DSP::release(). Unfortunately, I think that such a timer thing would be running in a different thread, and FMOD does not support calling from different threads. so that option is out.

Here is what I will try next:

I will keep a list of notes to delete, and the times that they were put in the list. When I note is to be ramped down and deleted, I will call SetVolume(0), and put it in the deletion list with it’s timestamp. Then, at some point later on (probably the next time a note is to be turned off), another function gets called, and it’s job is to check that notes who have had enough time to ramp down are deleted. It iterates the list, and checks the recorded time against the current time, deleting ones older then ~10msec (or whatever). seems a little busy to me, but it should work.

comments? suggestions? criticisms? corrections?

  • You must to post comments
Showing 5 results
Your Answer

Please first to submit.