Hello, this is my first post..!
I want to make a kind og music tracker using FMOD Ex, so my question is how to play sequences of samples precisely? For example, how do I play one sample at one moment and then play two other samples exactly one second after and at the same time (I would like an example in C#).
- Noufardn asked 11 years ago
By having taken a long look at the Modplug Tracker code, the delay/interval of the modplug tracker thread or timer (I don’t know which it is) is not as accurate as 1ms. It doesn’t even look MPT uses a multimedia timer as far as I remember.
Your app should just be able to act at tick intervals. For an IT module at T120 speed 6, the tick interval is the same as for a T120 speed 3, that is about 20ms. FMOD enables you, if your app can’t be responsive enough, to delay a sound triggering. Don’t have looked how much.
Normally, if you have succeeded in using multimedia timer, you can do what you’re looking for. It depends on whether it’s 1ms accurate or 15.
With Queue timers I have managed to making a functionnal beginning of sequencer, so FMOD is not incriminated.
[quote="Noufardn":3kys6h58]multimedia timers – it is part of new versions of the Windows API and is used with methods like timeSetEvent. From a bit of experimentation I found that this timer is actually quite accurate! [/quote:3kys6h58]
Ah yes it’s interesting, how accurate was this timer event ?
Regarding the code you’d like, if you look into the 2004/02/26 released code of Modplug Tracker (can be found at sourceforge.net), it looks like the code uses only timers and threads. However, it’s in no way a problem for the users: A module song played twice sounds the same twice (for a human being), so I think you don’t have to bother for the special DSP.
I have another question : OK, multimedia timers etc should be ok for sequencing sounds, but how to sequence sounds for non realtime rendering ? (for example a wav or mp3 writer)
[quote:3a7c1uws]Ah yes it’s interesting, how accurate was this timer event ? [/quote:3a7c1uws]
It depends on your machine but on my very old machine it seemed to be very precise within 1 ms.
[quote:3a7c1uws]how to sequence sounds for non realtime rendering ? (for example a wav or mp3 writer)[/quote:3a7c1uws]
Well if it is non realtime then it is not sequencing, I think.. but I guess you can render realtime and get FMOD to output to a file…?
About the DSP callback I think it is necessary. I’m thinking about playing two samples at the same time – in special cases you can actually hear these small delays – if for example you play the same sound twice at the same time where each sound is panned to left and right – if one of the sounds is played just a little bit later you can hear a kind of stereo effect (i used that trick when I made music with Fasttracker..)
btw I made a DSP callback work with some PureBasic code.. with C# i however get some strange protection errors..
I still don’t understand why the rhythm in the examples above is not completely ‘steady’.. is it because FMOD tries to play the sound immidiately and nothing is really immidiate with computers? I guess the problem would be solved if it was possible to tell FMOD to play the sound some short time in the future – then FMOD would have a chance to do the mixing ahead and make sure that the sound is played exactly where I want it to..? (would Channel::setDelay be able to do that?)
but OK.. since Channel::setDelay is not implemented I have to make my own mixer.. but how can I then take advantage of the built in effects…? I guess I cannot..
The delay you’re talkin about (the delay causing the stereo effect like the one achieved with the Offset command in FT2) can happen in FMOD ?
I ask this because I thought when a sound is triggered, it is played at the beginning of the next sound buffer . That is, if you play two simultaneous samples, they will both trigger at the exact same time. But I can be totally wrong !
If not (I have not checked both cases), a DSP should indeed be coded for what you need.
Some sample code on what you’ve managed doing would be a cool thing.
When you call playSound to play a sound, the sound cannot be heard at the exact time the function/method was started, because if I’m right, the mixer can’t write sound data in the playing cursor block. I’ve seen something like that many years ago : you can’t lock a sound buffer if it is occupied by the playing cursor.
So the mixer has to write its sound in the next free available block.
You can try changing your buffer size to see if it helps. Brett said FMOD mixes in 1024 sample blocks by default, but for example blocks of 64 samples are possible to achieve, and it will multiply your block accuracy by 16. It’s still not perfect, but in my opinion, it can fit most non-professional uses. Modplug uses a timer, but I don’t know how its mixer works (written partially in assembler in 1994).
If you intend to be 1 sample accurate, it’s as Brett said, you’ll have to write a mixer that can act so.
[quote:8n9t8zcx]The delay you’re talkin about (the delay causing the stereo effect like the one achieved with the Offset command in FT2) can happen in FMOD ? [/quote:8n9t8zcx]
If you make two calls to playsound I think you can be unlucky that they are put into different buffers..
[quote:8n9t8zcx]Some sample code on what you’ve managed doing would be a cool thing.[/quote:8n9t8zcx]
Don’t know if you’re a PureBasic user..? (see http://www.purebasic.com) this is the very simple code:
[code:8n9t8zcx]#FMOD_INIT_NORMAL = $00000000
FMOD_HARDWARE = $00000020
FMOD_LOOP_OFF = $00000001
FMOD_CHANNEL_FREE = -1
Procedure DSPCallback(a, b, c, d, e, f)
CallFunction(0, "FMOD_System_Init", system, 32, #FMOD_INIT_NORMAL, 0)
description\read_ = @DSPCallback()
CallFunction(0, "FMOD_System_CreateDSP", system, description, @dsp)
CallFunction(0, "FMOD_System_AddDSP", system, dsp)
CallFunction(0, "FMOD_DSP_Remove", dsp)
CallFunction(0, "FMOD_Sound_Release", sound)
CallFunction(0, "FMOD_System_Close", system)
CallFunction(0, "FMOD_System_Release", system)
[quote:3ekxgc47]So the mixer has to write its sound in the next free available block. [/quote:3ekxgc47]
Then I don’t understand why my first sample code doesn’t sound right – in that code PlaySound is called from a DSP playback that is called once for each block – so every time I call PlaySound the sound should be put exactly at the start of the following block? it does not sound like that..
[quote:he8m380l]Thats what System::lockDSP / System::unlockDSP is for, you can wrap playsounds in that and it will guarantee multiple channels to start together. [/quote:he8m380l]
OK I tried that, but the rhythm still isn’t completely steady.. why? is it, as suggested above, because nothing is ever really immidiate with computers, and would it be possible to make the rhythm precise if I could tell FMOD to play the sample some time in the future so that FMOD would be able to mix in the sound at the correct moment..? (by using Channel::setDelay, for example – if it were implemented)
if I somehow implement my own mixer, it will not be possible to use FMODs built in effects, right?
This guy tackled timing problems in a MIDI sequencer using C#. Code is well documented. Read the comments section where different approaches were discussed and tried. Might save you some reinventing of the wheel.
I am not a proficient programmer, but would love to see the basic framework for a “real-time” sample-based sequencer worked out using FMOD and C#. If it is possible.
I’m trying to sequence streams using FMOD Ex C# for a sequencer (wheelsofsteel.sf.net)
I figured this could be done using a custom stream object, which provides a read function that mixes data itself from the data returned by calling readData on each of the streams in the sequence…
…but so far is just crashes with a internal null pointer exception
Does this sound like a good approach?
- rowanseymour answered 11 years ago
I think that you could achieve this kind of delay using timers or a thread.
The only problem is that timers (and threads also) in Windows are about 15ms accurate. I you don’t mind this, that’s ok but I think a decent multimedia application (music oriented) should be able to be about 1ms accurate.
There are various articles out on the web (I’ve read some for C++) and techniques to do so (maybe not in C# but who knows)
For C#, it looks that there is the Sleep(…) static method in the System.Threading ‘package’. Look at http://msdn.microsoft.com/library/en-us … pTopic.asp
for more info.
For timers, I don’t know if it’s of any help, but you might take a look at
http://msdn.microsoft.com/library/en-us … stopic.asp
Hope it helps
Another link. Same programmer wrote a C# wrapper for the Win32 Multimedia timer.
To me, it’s an very interesting way to work, but you might have a look at and start a test from the user created sound example. It fills a stream buffer in realtime, and it works very well.
You have to test whether you use readData well. For some time I had problems getting data from a sound because I used arguments badly.
Maybe your problem comes from it.
thanks, but I think a normal timer is way too inaccurate and unpredictable (sometimes timer events fall out I think). From the documentation of threads it is unclear how accurate they are, but I suspect that they are not accurate enough – I read some people talk about ‘multimedia threads’, but I don’t know what that is…
according to this post:
http://188.8.131.52/forum/viewtopic.php … edia+timer
there is an FMOD method ‘setDelay’ that looks very useful, but it is not implemented in FMOD Ex..
otherwise I guess I could make my own DSP unit-callback that FMOD will call precisely every 25 ms before the sounds are mixed – then I could make sure that to sounds are played precisely at the same time, I guess.
but I don’t know if this is the ‘correct’ way to do sequencing..
I wish I could find some example for making that kind of DSP unit…
Please login first to submit.