Perfect video and audio: 'I'm unable to pull off'

byuu - Feb 21, 2008

I've tried to get bsnes in sync with perfect video and audio. For many years. It's another of the major things I'm unable to pull off myself.

I have code that allows the CPU to run up to 0.2 seconds ahead of the SMP, and vice versa. This means that in a given emulated video frame, the number of samples generated are wildly different.

By disabling this out-of-order execution, I take a 10-20% speed hit, but I get a more consistent number of samples per frame.

Even with the out-of-order execution disabled, and a lowpass buffer that adds a good 50-100ms latency, and a high-end 4-tap hermite filter to resample audio, I'm unable to get the audio to sound right.

It seems the lowpass buffer just continues to either grow or deplete at a constant rate, eventually the queued samples overflow and you get a horrendously different number of samples for one quick burst.

The resampling causes very noticeable pitch differences every time it's not by roughly ~20 samples or less. So either you go with what I have now, and you get wildly different pitches constantly for every packet that plays; or you take the speed hit, execute in sync, and buffer to hell and back, and end up with smooth audio for 3-4 seconds, then hear a really, really off pitch block for ~20-40ms.

Vblank + smooth audio is the last killer feature I really want in the emulator, but you'll find dozens of pages in this thread where I've tried to pull it off and failed. I don't know why everyone else can do it but me, but they can and I can't.


tetsuo55 - Feb 21, 2008

Okay, i want to crack this nut

How does the snes do it?, the sound doesn't crackly, but the image would still tear.

So we have to fix the sound crackle before we can fix the tearing

On hardware fixing the tearing would simply be done by slowing the snes down to exactly 60fps (easier said then done), doing this would slowdown the sound to and slightly change the pitch, but the change would be constant.

So how does the communication between the cpu and the smp work in the real snes and what is bsnes doing differently from that?


Verdauga Greeneyes - Feb 21, 2008

tetsuo55 wrote:
How does the snes do it?, the sound doesn't crackly, but the image would still tear.
So we have to fix the sound crackle before we can fix the tearing
On hardware fixing the tearing would simply be done by slowing the snes down to exactly 60fps (easier said then done), doing this would slowdown the sound to and slightly change the pitch, but the change would be constant.
So how does the communication between the cpu and the smp work in the real snes and what is bsnes doing differently from that?

SNES -> TV is very different from bsnes -> PC -> monitor/TV. Operating systems implement all sorts of buffering and most sound cards work at 48000 (sometimes even 44100Hz?) internally. I don't know the technical details about what the TV does with the SNES' analog audio signal, but you can see the process is much more direct.

As for how bsnes is different from how the SNES works, remember that the SNES contains several specialised processors that work in parallel at different speeds (again I don't know the technical details, so bear with me). The SNES doesn't need to synchronise, components just poll eachother for their current states. What I don't know is if video and sound are output at their own independent speeds, but they are generated independently without any hassle. bsnes builds up a buffer of frames while going back and forth between the different components to keep them synchronised, but I don't know how it chooses when to output (does it just wait until a certain threshold is reached?). Even so, I expect it can only do this on synchronisation events, and since components aren't, as byuu mentioned, forced to run lockstep, the amount of frames it has to output differs wildly each time.

By the way, this reminded me, I recall a major problem with video synchronisation was that D3D has some big latency issues with wait-for-vblank calls? And it was mentioned that these problems might not be present in OpenGL.. now that Linux has OpenGl support, have you checked if this is the case?


tetsuo55 - Feb 21, 2008

I am aware of these limitations, working around them is not a priority, getting the audio to stop crackling is for now.

So what google tells me is that the spc700 recieves "code" which it executes together with its DSP, there is no feedback to the snes CPU, so it would seem that the spc700 just runs through the program it gets and doesnt care about the rest of the snes

The game is written in such a way that the sound doesnt go out of sync or wacky or whatever.

Also according to google the spc700 except a startup header to play the track/sample/fx

---

nevermind, my train of though would kill bsnes(it would basically mean breaking down bsnes to the point where everything is emulated at its native speed, as you would need to let the mpc run independantly whitouht gettign the audio out of sync) mame seems to be able do this though, with discrete audio emulation

-----

Lol i think i just explained why sound crackles Razz


FitzRoy - Feb 21, 2008

The confusion is likely coming from the fact that there are emulators that have it and face similar translation of hardware problems, so people assume that it's not hard in bsnes. But this feature is almost as popular as savestates, and if it were easy to do, a blargg or Nach would have come in and done it already. So it obviously isn't. I don't know why I forgot to put it in my unsupported feature list. It's there now.

I agree, though, that opengl should be explored. I have the faint hope that vsync is somehow easier with it.


byuu - Feb 21, 2008

OpenGL is even worse. You have no control over it. You can request a double buffered visual, but that's it.

For nVidia, you have to run nvidia-settings to enable or disable vsync globally. It can't be controlled through software.

Worse yet, it's not page flipping (obviously, other stuff onscreen), meaning it's even slower. And in this case, with no audio output, I can't even get smooth video to fill the screen. I have to use a ~3x scaler on my 1920x1200 monitor. Anymore and the top of the video will still tear. Basically because it's taking too long to blit the new video to the screen that the vblank period is running over.

And even more damning, is that there is no DirectSound on Linux. The best there is, is OpenAL. You can only query when entire buffers have completed, rather than just asking where the current playback cursor is at. That makes predicting how much you need to resample your current audio block by that much harder. You basically need to add lots more, much smaller, blocks and even then, you'll be worse off than with DirectSound.

Linux is just ... dark ages with this stuff. Video, audio, input ... it's no wonder most companies won't even port games to Linux. Linux' APIs just suck royally. Microsoft is light years ahead with DirectX.

Quote:
But this feature is almost as popular as savestates, and if it were easy to do, a blargg or Nach would have come in and done it already.

Yeah, I'm sure someone would have added it by now if it were easy. I've considered offering a bounty on it, but I'm afraid that the quality of code written for money will be far, far worse than code written by someone passionate about the issue.


© 2008 ZSNES board - www.emusource.net/bsnes/index.html