framerate calculation error - alternative way?

Started by
14 comments, last by Rockoon1 15 years, 5 months ago
hi, my almost finished game do all the graphic-stuff framerate independent. so i have to calculate the framerate wich should be no problem. but i have a mysterious (for me ;) problem doing this. Here my code for calculating the framerate:

void TicTimer(void) {
	double static FPS, tmpFPS;
	double static AvarageFPSStartTime;
	LONGLONG static lastFrame;
	LONGLONG CurrentFrame;
	double static AvarageFPSCounter;

	if (freq > 0) {
		QueryPerformanceCounter((LARGE_INTEGER*)&CurrentFrame);
		elapsed = CurrentFrame - lastFrame;
		if(elapsed > 0) FPS = (double)((double)freq / (double)elapsed);
		else FPS = 1;
	} else {
		timeBeginPeriod(1);
		CurrentFrame = timeGetTime();
		timeEndPeriod(1);
		elapsed = CurrentFrame - lastFrame;
		if(elapsed > 0) FPS = 1000.0/elapsed;
		else FPS = 1;
	}
	
	fFrameRate = fFrameRate*0.9f + FPS*0.1f;

	lastFrame = CurrentFrame;
}

i think this should be right. in my game i do some realtime sound-synthesis (its a sound-toy-game). when i exclude the soundsynthesis in my code the framerate-calculation is stable (60 frames like my monitor) but when i do the synthesis the framerate is rising! and changing all the time. but when i measure the framerate with an external tool (FRAPS) it shows allways the constant 60 frames which is right. so there must be an error in my calculation code but i can't find it. can anybody help me? i doing all the stuff in c++/directx. is there any other way for calculating the framerate? do anybody know how fraps is doing this?
Advertisement
What is 'freq'?

When you say your framerate is rising and changing all the time, could you give a few more details. What range of values is it changing between, or how far / fast is it rising?
The Trouble With Robots - www.digitalchestnut.com/trouble
freq is the performance-counter frequency at the start of the game. so if freq is 0 this means that the pc has not any performance-counter.
but that does not matter even with the normal timeGetTime the framerate is changing.
the framerate is changing very fast (a few times per second) between 60 and round about 170 frames. which is very strange because without the soundsynthesis switched on the framerate is stable at the monitor frequency (60 frames).
Is it possible that the sound synthesis is manipulating the performance counter?

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

even without the performance counter (by using timeGetTime) the framrate is changing. how could i manipulate the performance counter?

the way i doing the framerate calculation should be ok!? then the sound- synthesis must distorting the measuring of the time for one frame in any way!?
i dont know what to do. ok, i will have one more look at my code.
try turning your GPU's vsync off and see if that makes any difference.
[ dev journal ]
[ current projects' videos ]
[ Zolo Project ]
I'm not mean, I just like to get to the point.
without vsync the framerate is also changing between 300 and 500 fps when the fraps fps counter is almost stable at 330 fps.

strange thing i tested:
in every frame the checkDSStream function is testing if the directsound ringbuffer is ready to fill. with the directsound-methode "GetCurrentPosition" i get the current soundcard-read-position of my ringbuffer. if the readposition is in the first half of the buffer, the second half of the buffer will be filled with data and vice versa. the DSStreamData function is filling the buffer. the for loop represent all the sound calculations (i replaced the original calculations with this useless calculation only for testing). the loop should waste time.

void checkDSStream() {	DWORD playPos;	lpDSBuffer->GetCurrentPosition(&playPos,NULL);	if(playPos < 8192*2 && soundBufferSwap == 0) {		soundBufferSwap = 1;		for(long i=0;i<10000000;i++) dummy = (i*0.01f)*(i*0.01f)*(i*0.01f)*(i*0.01f);//		DSStreamData(1);	} else if(playPos >= 8192*2 && soundBufferSwap == 1) {		soundBufferSwap = 0;		for(long i=0;i<10000000;i++) dummy = (i*0.01f)*(i*0.01f)*(i*0.01f)*(i*0.01f);//		DSStreamData(0);	}}



when i commend the DDStramData (like in the code above) i obviously can't hear any sound. but the framerate is also changing. when i rise the number of loopcycles of the for-loop the framerate is also rising.

if i'm changing the checkDSStram() like this (for testing):
void checkDSStream() {	DWORD playPos;	lpDSBuffer->GetCurrentPosition(&playPos,NULL);	for(long i=0;i<10000000;i++) dummy = (i*0.01f)*(i*0.01f)*(i*0.01f)*(i*0.01f);}


the framerate is falling when i'm rising the loopcycles like normal. the only difference between the codes is that in the top code the calculation is not done every single frame (the soundbuffer will not be filled every frame only when the readposition has passed half the buffer) and in the second code the calculation is done every frame.

so how could this cause the framerate risings?
i would be very pleased if anybody have a suggestion.



What's this for?

fFrameRate = fFrameRate*0.9f + FPS*0.1f;


It looks a bit dubious to me. Is it meant to 'smooth out' the framerate? If you want an FPS counter that is nice to look at, I just count how many ticks run in a second and update the counter at the end of that second. The number only changes once a second so it's nice to look at (not some flickering number).

Otherwise, the immediate framerate is 1 divided by the time step, which it looks like you're doing correctly.
Construct (Free open-source game creator)
fFrameRate = fFrameRate*0.9f + FPS*0.1f;

is for smoothing. it's the eaysiest way. of course you can do it in some other way. but that doesn't matter.

now i have isolated my problem. when i'm doing some calculations every single frame like this:

for(long i=0;i<10000000;i++) dummy = (i*0.01f)*(i*0.01f)*(i*0.01f);

the framrate is going down to stable 25fps (on my pc). but when i do this calculation evere 10ths frame (or something like that but not every single frame) the framerate is rising and changing all the time. i suppose the framerate should still going down but it is rising and going wild. how could that be?

and of course the framerate shown by the external FRAPS framerate counter is allways stable 60 frames. only when i doing the calcultion every single frame the framerate is also going down to 25fps.

do anybody have any suggestions?
ok, here is the final problem:

i saved all the frametimes in a file. when i dont't do this stupid calculation:

for(long i=0;i<10000000;i++) dummy = (i*0.01f)*(i*0.01f)*(i*0.01f);

the time for doing one frame is around 20ms. when i do this calculation every 5th frame the time for rendering this frame will cause 100ms. that obviously ok. but the frame after this stupid calculation will only cause 1ms and so the framerate is rising up to 1000fps in this frame.

how could that be?

This topic is closed to new replies.

Advertisement