I’m new to FMOD, so please forgive my ignorance.
I’m making a fairly simple C# program that basically plays loops (wavs etc) in a certain order, based on user input The samples should be played after each other seamlessly in the current bpm (I don’t need them to follow bpm like rex files or anything though, they have to be prepared to have the correct bpm).
So, I have a timer (using the C# Midi Toolkit from codeproject.com, so it’s a multimedia timer) that fires ticks, and if enough ticks has passed, it calls a system.playSound. This works fairly well most of the time, but every now and then there is a slight glitch, as if the sample is triggered a bit too late. I tried using "system.setDSPBufferSize(64, 1);" because I read somewhere this might help, but it’s still there. Anything else I can try?
An additional question, if I load the same sample twice (different parts of my program happen to need it), will it occupy more memory, or is this handled by FMOD? Should I write code that checks if it is already loaded? Can I play the same sound multiple times (ie polyphonic) if I only load it once?
Thanks for your time!
- errorist asked 9 years ago
Sorry for triple-posting, but I just wanted to let you know that I seem to have gotten it to work with this method, and I wanted to share. If anyone sees any problems with it, let me know.
(btw this is code from a test application, so it’s not perfect by any means)
So, I first play a sound to get the start position :
this.system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
uint low = 0, high = 0;
channel.getDelay(FMOD.DELAYTYPE.DSPCLOCK_START, ref high, ref low);
This gives me a starting position in two uints, which can be converted to one ulong using the method above.
Then I find the delay (in ulong) using this (ticks is the amount of ticks by my multimedia timer, which has 48 ticks per beat):
float mili = ((float)this.ticks / (float)(bpm * 48) * 1000);
ulong position = (ulong)(4.8 * mili) + this.start + this.latency;
and this gives me the position (in ulong, so convert first) for my setdelay. So I play the sound with the paused option, set the delay, and then use setpaused=false.
This seems to work pretty well, but please let me know if I’m doing anything wrong.
Just an update, I tried doing the same thing with another library (don’t know if it’s ok to mention the name, so I won’t), and it seems to do the trick. However, it has fewer features (no channels/channel groups, so I had to simulate channels by keeping an arraylist of the sounds and changing all their volumes, but it works).
I would still prefer to use fmod, because the routing options seem superior which I might need in the future, but for the moment I’m good. But if anyone knows a solution, please let me know. Thanks!
You can tell a sample to start on an exact sample tick with Channel::setDelay.
You can also stitch sounds together with Sound::setSubSampleSentence.
Dont change setDSPBufferSize the values you set mean you dont really understand what it does. ‘1’ as numbuffers will not work, you need at least 2 buffers to stream audio (doublebuffer). Setting it to 64 would more than likely also cause some glitching as that is a pretty small value.
The function probably returned an FMOD_ERR_INVALID_PARAM error but you didnt catch it.
Thanks for your reply. You’re right, I don’t know a lot about fmod or sound programming in general, so I did not understand setDSPBufferSize very well, but if I set 2 as numbuffers, I get a strange hissing sound even when nothing is playing.
The stitching doesn’t seem to be an option, I don’t always need to trigger sounds right after each other, I need to trigger them at the right tick. Or maybe I’m missing something?
Could you (or someone else) please elaborate on how I could use setDelay? I’ve read the manual but I don’t get how it works, and the forums don’t seem to have a lot of information about it either. Is there some sample code somewhere?
Okay, after giving it some more thought I think I (kind of ) get it. Am I correct in assuming this would be the basic structure :
- Right at the moment I start my song, I use playsound (possibly with a dummy sound), and use getDelay to get the starting point.
- Every tick where I need to start a sound, I use playsound, and give it a delay with setDelay
- This delay would be calculated using this starting point and the current bpm (with every second being 48000 ticks in the dsp clock).
The only thing I can’t wrap my head around, is the wraparound stuff. The help files say to use FMOD_64BIT_ADD, but I don’t find any C# equivalent. Could anyone give me an example on how to use this?
Edit : Am I correct in assuming the 64 conversions could be done like this in C#?
ulong lng = (ulong)hi * 2147483647L + (ulong)lo;
lng += 1234; // whatever
hi = (uint)(lng / 2147483647L);
lo = (uint) Math.Floor((decimal)(lng % 2147483647L));
Please login first to submit.