-
Help with SDL and Timing
Hi there, i dont know if this is the right place to post this, but there is no SDL forum so...
ok my problem is that im using this code to get a sound after another:
Code:
if ((SDL_GetTicks()-timing) >= (60000/y))
{
Mix_PlayChannel(-1,clap,0);
timing=SDL_GetTicks();
}
the only problem is that the time between the sounds should be constant and it isnt, the sounds delay some time and thats not good, because i need TOTAL PRECISION.
How can i solve this?? help pls.
BTW: i believe the problem is infact the timing and not the sound... cause when i if ((SDL_GetTicks()-timing) == (60000/y)) do this the sound never plays, so i can i set the time delay (Im not talking about SDL_Delay() of course), so it would be exact??
-
-
here it is;
Code:
while (quit==0)
{
apply_surface(bg, screen,0,0);
if (SDL_PollEvent(&event))
{
//Quit Metronome
if (event.type==SDL_QUIT)
{
quit=1;
}
//--------------------------------
if (event.type==SDL_KEYDOWN)
{
SDL_EnableUNICODE(SDL_ENABLE);
if (event.key.keysym.unicode>=(Uint16)'0' && event.key.keysym.unicode <=(Uint16)'9')
{
if (x<11)
{
time_str[x]=(char)event.key.keysym.unicode;
x++;
text=NULL;
}
}
if (event.key.keysym.sym==SDLK_RETURN)
{
x=0;
while (x<11)
{
time_str[x]=' ';
x++;
}
x=0;
text=NULL;
}
}
text=TTF_RenderText_Solid(font, time_str, textcolor);
}
y=atoi(time_str);
if (y<=0) y=1;
if ((SDL_GetTicks()-timing) == (60000/y))
{
Mix_PlayChannel(-1,clap,0);
timing=SDL_GetTicks();
}
apply_surface(text, screen,0,0);
SDL_Flip(screen);
}
the full loop
-
And how do you expect your timing to be precise when there is a lot of stuff in your loop?
-
Ok tks for the help... -.-
now i request REAL help, how can i fixx it pls??
oh and btw... this is not too much stuff for a loop.
-
Why you both use an if block to see time is passed and SDL_Delay together? Surely when delay is called for 6000ms, 6000ms is passed.
-
I thought of that, but doesnt SDL_Delay stops the entire loop??
-
Yes.
Code:
if ((SDL_GetTicks()-timing) == (60000/y))
You meant
Code:
if ((SDL_GetTicks()-timing) > (60000/y))
?
-
if ((SDL_GetTicks()-timing) >= (60000/y))
Yes, i meant that, sory lol. but i cant stop all the program cause while the sounds are playing i need imput too, is there any other way arround this??
-
I don't get you. You already used SDL_Delay. Remove that or remove if block. You should remove if block or you will miss some events. Remove it and send new code with results.
Code:
x=0;
while (x<11)
{
time_str[x]=' ';
x++;
}
You can make it a for loop. And what this loop supposed to do? Why putting space in time_str?
-
*facepalm* the code was wrong sory -.- that was a test i was doing,
the right code is without the delay lol.
oh and yes that fills up all the spaces in time_str with spaces so we can rewrite it.
btw i updated the old code to the right version lol ^^^^ go check it out now xD
oh and if i put the delay only it doesnt let me input nothing, because it is constantly delaying, wich stops the entire program
-
This way I think you are missing events. You poll them, but time is not elapsed enough so event is discarded. Make it like
Code:
while (quit==0)
{
apply_surface(bg, screen,0,0);
if (((SDL_GetTicks()-timing) == (60000/y)) && SDL_PollEvent(&event))
{
//Quit Metronome
if (event.type==SDL_QUIT)
...
Mix_PlayChannel(-1,clap,0);
timing=SDL_GetTicks();
//Without if
-
Nop, it doesnt work, because to get the imput both conditions need to be positive, and thats very hard to happen.
I tried changing the "and" to an "or" ( || ) but it didnt worked either, cause with a or every time i moved the mouse for example it would play the sound...
help pls...
-
Sorry make it >= instead of ==. I copied from wrong code. It should be &&. You may need to revise your whole loop (make it a do..while).
This means that events should not be polled unless the enough time is elapsed. Sure it will work. If the second condition is false we have no input. f the first one is false, no event should be polled.
Inputs are queued in event queue.
Use to put space into a string. Anyway I think this part is redundant but to be sure I should see whole the code.
-
Code:
if (((SDL_GetTicks()-timing) >= (60000/y)) && SDL_PollEvent(&event))
{
//Quit Metronome
if (event.type==SDL_QUIT)
{
quit=1;
}
//--------------------------------
if (event.type==SDL_KEYDOWN)
{
SDL_EnableUNICODE(SDL_ENABLE);
if (event.key.keysym.unicode>=(Uint16)'0' && event.key.keysym.unicode <=(Uint16)'9')
{
if (x<11)
{
time_str[x]=(char)event.key.keysym.unicode;
x++;
text=NULL;
}
}
if (event.key.keysym.sym==SDLK_RETURN)
{
x=0;
while (x<11)
{
time_str[x]=' ';
x++;
}
x=0;
text=NULL;
}
}
text=TTF_RenderText_Solid(font, time_str, textcolor);
Mix_PlayChannel(-1,clap,0);
timing=SDL_GetTicks();
}
u mean like this?? (btw ty for the string function lol, ill change it latter.. when i solve this major problem :\
-
Yes I meant that. But its wrong because if no event is queued no sound will be played. There are alternatives...
But I feel so sleepy and can't think... I better go to bed. Good night!
-
Why it fills time_str with one unicode char 11 times?
-
that is not important for this question, pls just help me get the timing right...
the last code didnt worked either, the timing still has some delay :\
Help pls
-
Sorry but I should understand your code before doing anything to it.
One way is to make a provider and a consumer thread. Provider provides the sequence to be played by consumer thread.
I thought it would be hard for you. To find an easier way, I need a very clean code that I fully understand.
-
hmm can u explain that "provider" metod pls??
oh and btw if u really need to know, it fills time_str in every position (except [12]) with space, so it needs to loop 11 times.
-
I mean why time_str has 11 chars?
Provider thread is a thread you write to set the time_str.
-
the time_str has 11 chars because it is a string, that will then turn into an integer, this means that the max number of that integer is 99999999.
-
As you are filling that string yourself, there is no need to have a string at all. You can put it directly to an int.
-
Its for saving the string into a surface, so the user can keep track of the value
-
I didn't tested it. Just a proposal.
Code:
while (quit==0)
{
apply_surface(bg, screen,0,0);
y=atoi(time_str);
if (y<=0) y=1;
if ((SDL_GetTicks()-timing) == (60000/y))
{
if (SDL_PollEvent(&event))
{
//Quit Metronome
if (event.type==SDL_QUIT)
{
quit=1;
}
//--------------------------------
if (event.type==SDL_KEYDOWN)
{
SDL_EnableUNICODE(SDL_ENABLE);
if (event.key.keysym.unicode>=(Uint16)'0' && event.key.keysym.unicode <=(Uint16)'9')
{
if (x<11)
{
time_str[x]=(char)event.key.keysym.unicode;
x++;
text=NULL;
}
}
if (event.key.keysym.sym==SDLK_RETURN)
{
x=0;
while (x<11)
{
time_str[x]=' ';
x++;
}
x=0;
text=NULL;
}
}
text=TTF_RenderText_Solid(font, time_str, textcolor);
}
Mix_PlayChannel(-1,clap,0);
timing=SDL_GetTicks();
}
apply_surface(text, screen,0,0);
SDL_Flip(screen);
}
-
nop that doesnt work, it doesnt let me input nothing and the program enters in an infinite loop cause the events only happen when ((SDL_GetTicks()-timing) == (60000/y)) and when i input something AT THE SAME EXACT TIME, wich is impossible. and besides it still delays a little bit.
the delay has to do with lots of things (cpu speed... etc...) and what i want to know is how to round that and i want to know how to get THE PERFECT TIMING.
-
If SDL has an event queue maybe you need to call PumpEvents() just before if block in my last post.
-
I recommend using OpenAL or some other better third party sound API. FMOD is also one I would recommend. I'm assuming SDL is trying to offer a very basic sound system so it is easy to get simple sounds playing but probably was not designed to be a fully featured sound API.
-
I also have problems like that!Thanks for answer and help!^^
-------------------------------------------------------------------------------
Learn more about our Fashion Games website.Fashion Games