libretro/virtualjaguar-libretro

Problem with sound sync , fps cap at 46.8

r-type opened this issue · 10 comments

it seem sound sync caps the framerate to 46.8/47 fps.

Seem to be related to soundbuffer wich expect 2048 samples.
so for now it sound good but framerate is always around 47 fps.
RATE = 48000 , BUFFER 1024 (*2 channel 2048)
so 48000/1024 = 46,875 which is what i get in fps for now in all games.

if i set falsely
info->timing.sample_rate = 61440;// instead of 48000;
61440/1024 = 60 fps .
Now games run at full speed and sound is always correct.

Interesting, this didn't come up in my OE port. Probably revealed by how RA syncs audio. I'm going to simplify the audio callback a bit and then we can look into this more.

I don't get a fps speedup by changing the sample rate, at least not with stock settings in RetroArch. Maybe I'm missing something though.

Anyway, I've simplified the callback a bit to move out code I added into the emulator's run loop so it should be cleaner now: d9b4166

So the extent of my changes are removing the SDL calls and changing the audio buffer from uint8 to uint16: https://gist.github.com/anonymous/b4d78e564b1cb127715a

It's definitely spending a lot of time in the while loop here which is eating up cpu https://github.com/libretro/virtualjaguar-libretro/blob/master/src/dac.cpp#L216-L230

Any thoughts?

Yes it only append for me if in Audio options, Audio Sync enable is on . (was my case)
and yes your clean up make thing easier to read for sound callback .

i'm always trying to understand how sound should be deal .( why they should use a 2K buffer as in 48000 at 60hz that give normally 800 (*2=1600) ).
BTW this give the same with 2048 buffer or 1600 , 554 cycles to run .

48000/2048 = 23,4375 (48khz and 2K buffer)
1/23,4375 =0,042666667 sec to run
26590906 Hz -> 0,042666667×26590906 = 1134545,322666667 cycles
1134545 / 2048 = 553,977208333 (554) cycles to fill the buffer

48000/1600 = 30 (48khz and 1.6K buffer)
1/30 0,033333333 sec to run
26590906 * 0,033333333 = 886363,533333333 cycles
886363,533333333 /1600 = 553,977208333 (554) cycles to fill the buffer

Else ,not related ,but for videobuffer conversion (RGBA to XRGB ) why not simply use

// Virtual Jaguar outputs RGBA, so convert to XRGB8888
videoBuffer[h]>>=8;

as we don't need alpha.

I close since it's not an issue , it's the way retroarch audio sync works ,
if i disable audio sync , then it run at 60fps.

I have test with an audio sound buffer set to 1600 instead of 2048 and now i get 60fps with audio sync on . for what i have tested the audio sound correct to me ( like with buffer set to 2048) .
if you have time to test it and tell me if it sound good for you?

You'll have to tell me what exactly you changed (lines and values) so that I can replicate on my end.

I'm pretty sure all the audio is set up wrong both from VJ's internal callback and in the core implementation. Perhaps someone that knows audio really well can help diagnose like @kode54

r-type@70e5a5c

I recreate sound callback to not touch your previous code and all change are in libretro.cpp.
( if you can test to see if you notice diff in sound with 1.6k buffer) .

with it sound seem to sound like yours for me and i got 60fps instead of 47 with audio sync set to enable. (tested only with doom,rayman,tempest2K )

I also use a simpler video RGBA -> XRGB conversion (we loose alpha but if you look tom.cpp it always 0xff for alpha) . screen result are the same.

Yes if you know someone with audio knowledge it could be useful if he take a look as i 'm not an expert . all i understand is we have to setup a JERRY callback every 20,83 sec (1000000/48000)
then handle JERRY events to execute DSP. means 554 cycles for our sound cb ( and then read right&left sample ) but also we have to handle other JERRY events .

I only have 30fps with this patch using stock/default RetroArch settings so something is wrong. What am I missing?

Whoops. Okay, so I discovered an issue with how RetroArch does syncing. It seems the more Finder or Terminal windows I have open and in view, the worse it affects syncing. Probably worth investigating on OSX.

Anyway, r-type it looks like your patch might solve the problem with VJ. Still taking a look.

Okay thanks, I merged your two changes:
14a97f4
49a119a

This still isn't completely 'right' though because the sound callback routine is using way too high CPU (95-100%) compared to standalone VJ which hits lower around 75% (though their sound in the latest source sounds broken). I wonder if we should roll back to the latest 'stable' version.

Something weird in their SDL port I noticed was that the SDLSoundCallback in dac.cpp returns a length
of 8192. Any other ideas on audio?