0
0

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#).

  • You must to post comments
0
0

Which method of interpolation is the best to use between samples (or groups of samples)?

  • You must to post comments
0
0

[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?

  • You must to post comments
0
0

http://www.codeproject.com/cs/media/MIDIToolkit.asp

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.

  • You must to post comments
0
0

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?

  • You must to post comments
0
0

Hello,
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

  • You must to post comments
0
0

http://codeproject.com/csharp/lescsmultimediatimer.asp

Another link. Same programmer wrote a C# wrapper for the Win32 Multimedia timer.

  • You must to post comments
0
0

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.

  • You must to post comments
0
0

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://52.88.2.202/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…

  • You must to post comments
0
0

Hey thanks for the info. If you’ve got other great stuff like that, please post them ; I’d be really grateful.

  • You must to post comments
0
0

Brett,

When you have time, could you go over in a little more detail what this custom mixer should be doing with FMOD to get 1 sample timing accuracy? Some pseudo code perhaps? I am not able to understand how the mixer keeps track of time and sound samples without some kind of timer.

  • You must to post comments
0
0

Ah cool someone else beside me is trying to implement a sequencer using FMODex.

  • You must to post comments
0
0

I’ve tried some different approaches to sequencing but no matter what I try the playback isn’t completely accurate – you can try the three sample codes below and probably hear that the rhythm is not a 100% precise (you need PureBasic, the fmodex DLL and a wav-file to try the samples).

I think the problem is somehow with PlaySound – the sound isn’t played precisely when PlaySound is called.. so how do I solve that problem…? (could it be that I have to use DirextX directly, instead of FMOD..?)

Below are the three different approaches I tried. In the first approach I used a DSP callback:

[code:vliwdbok]#FMOD_HARDWARE = $00000020

FMOD_SOFTWARE = $00000040

FMOD_INIT_NORMAL = $00000000

FMOD_CHANNEL_FREE = -1

Structure FMOD_DSP_DESCRIPTION
name.b[32]
version.l
channels.l
create.l
release.l
reset.l
read_.l
setposition.l
numparameters.l
paramdesc.l
setparameter.l
getparameter.l
config.l
configwidth.l
configheight.l
userdata.l
EndStructure

Global system, sample

Procedure DSPCallback(a, b, c, d, e, f)
Static delay
If delay = 0
CallFunction(0, "FMOD_System_PlaySound", system, #FMOD_CHANNEL_FREE, sample, #False, @channel)
delay = 5
EndIf
delay – 1
EndProcedure

OpenLibrary(0, "fmodex.dll")
CallFunction(0, "FMOD_System_Create", @system)
CallFunction(0, "FMOD_System_Init", system, 32, #FMOD_INIT_NORMAL, 0)

CallFunction(0, "FMOD_System_CreateSound", system, "lt.wav", #FMOD_HARDWARE, 0, @sample)

description.FMOD_DSP_DESCRIPTION
description\read_ = @DSPCallback()
CallFunction(0, "FMOD_System_CreateDSP", system, description, @dsp)
CallFunction(0, "FMOD_System_AddDSP", system, dsp)

Delay(2000)[/code:vliwdbok]

according to Brett (see http://52.88.2.202/forum/viewtopic.php … highlight=) this approach is however, for some reason, not recommended.. and you can hear that the timing is not completely precise..

so instead I tried using a multimedia timer:

[code:vliwdbok]#FMOD_INIT_NORMAL = $00000000

FMOD_SOFTWARE = $00000040

FMOD_LOOP_OFF = $00000001

FMOD_CHANNEL_FREE = -1

Global sample, channel, system

Procedure TimerCallback(wTimerID, msg, dwUser, dw1, dw2)
CallFunction(0, "FMOD_System_PlaySound", system, #FMOD_CHANNEL_FREE, sample, #False, @channel)
EndProcedure

OpenLibrary(0, "fmodex.dll")
CallFunction(0, "FMOD_System_Create", @system)
CallFunction(0, "FMOD_System_Init", system, 32, #FMOD_INIT_NORMAL, 0)
CallFunction(0, "FMOD_System_CreateSound", system, "lt.wav", #FMOD_SOFTWARE|#FMOD_LOOP_OFF, 0, @sample)

tID = timeSetEvent_(100, 0, @TimerCallback(), 0, #TIME_PERIODIC)

Delay(2000)

timeKillEvent_(tID)

CallFunction(0, "FMOD_Sound_Release", sample1)
CallFunction(0, "FMOD_Sound_Release", sample2)
CallFunction(0, "FMOD_System_Close", system)
CallFunction(0, "FMOD_System_Release", system)
CloseLibrary(0)[/code:vliwdbok]

But still it doesn’t sound right.. I was thinking this could have something to do with the way that Windows schedules execution of all the concurrently running processes on my computer, so I tried another aproach where I created my own thread to do the playback:

[code:vliwdbok]#FMOD_INIT_NORMAL = $00000000

FMOD_SOFTWARE = $00000040

FMOD_LOOP_OFF = $00000001

FMOD_CHANNEL_FREE = -1

Global sample, system

Procedure PlaybackThread(a)
SetThreadPriority_(GetCurrentThread_(), #THREAD_PRIORITY_TIME_CRITICAL)
For i = 0 To 16
CallFunction(0, "FMOD_System_PlaySound", system, #FMOD_CHANNEL_FREE, sample, #False, @channel)
Delay(100)
Next
EndProcedure

OpenLibrary(0, "fmodex.dll")
CallFunction(0, "FMOD_System_Create", @system)
CallFunction(0, "FMOD_System_Init", system, 32, #FMOD_INIT_NORMAL, 0)
CallFunction(0, "FMOD_System_CreateSound", system, "lt.wav", #FMOD_SOFTWARE|#FMOD_LOOP_OFF, 0, @sample)

SetPriorityClass_(GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)

CreateThread(@PlaybackThread(), 0)

Delay(3000)

CallFunction(0, "FMOD_Sound_Release", sample)
CallFunction(0, "FMOD_System_Close", system)
CallFunction(0, "FMOD_System_Release", system)
CloseLibrary(0)[/code:vliwdbok]

As you can see I set all priorities to the maximum possible, so no other process should be able to interfere with my thread – whenever it wants to play the sound it will be allowed to do that. However, it still doesn’t sound quite right.. so the problem must be with PlaySound, right?

BTW the last approach is similar to the way that ModPlug tracker does sequencing (as far as I could understand from the source code)

  • You must to post comments
0
0

[quote:2denavct]Ah cool someone else beside me is trying to implement a sequencer using FMODex.[/quote:2denavct]

yes, but are we all newbies..?! I think it’s strange, there seem to be no previous posts about sequencing.. I wonder if it is because of the redesign of FMOD.. I also tried to make a sequencer with the old FMOD, but I quickly gave up trying figure out that API… FMOD Ex seems very easy though..

btw, I looked into 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! however, I guess I cannot be a 100% sure that the samples will play at the same if I want them to, so I still think it will be better to use some kind of user (me) defined DSP callback. if only I could see an example…

  • You must to post comments
0
0

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.

  • You must to post comments
0
0

[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)

  • You must to post comments
0
0

that’s a bad news for me,
I don’t have a clue about how a mixer works. I don’t know how it can be accurate without taking 100% CPU time or using a a timer or a Sleep().

  • You must to post comments
0
0

[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..

  • You must to post comments
0
0

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..

  • You must to post comments
0
0

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.

  • You must to post comments
0
0

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.

  • You must to post comments
Showing 1 - 20 of 24 results
Your Answer

Please first to submit.