Real-time syncing the emu - why by video?

The Uzebox now have a fully functional emulator! Download and discuss it here.
User avatar
uze6666
Site Admin
Posts: 4449
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Real-time syncing the emu - why by video?

Post by uze6666 » Mon Oct 05, 2015 3:23 am

Normally it should sync on audio as was mentioned in previous posts.

Interestingly, with my recent fixes on the uzem140 branch, framerate jumped about 31Mhz with no sound. When added sound back with the video VSYNC flag on (and the SDL_Delay(0) before outputting audio), everything is perfect. No skips on the sound. I'm not sure I understand at this point why this is so. I had fixed the audio ring so that in case of underrun it emits the last sample, so perhaps that is why.
The audio should rather be output at given cycle intervals, so the wait should be rather tied to elapsed cycles: every 1820 cycles it should do this wait. This way even if the kernel changes or is goofed up the emulator keeps going. Or even if someone decides to process audio twice, outputting a second time mid-line to get ~31KHz. You could even ask a more sane (such as 48KHz) audio sampling rate from SDL then, and tune the elapsed cycles accordingly (597 cycles then).
Hmmm...interesting. So you mean a separate audio thread mixing at 22Khz and interpolating sample? It would pick the sample as you said at a regular 1820 uzem cycles. Didn't fully thought it up, but yeah, that could do it. :)

User avatar
Artcfox
Posts: 944
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Real-time syncing the emu - why by video?

Post by Artcfox » Mon Oct 05, 2015 3:33 am

uze6666 wrote:Normally it should sync on audio as was mentioned in previous posts.

Interestingly, with my recent fixes on the uzem140 branch, framerate jumped about 31Mhz with no sound. When added sound back with the video VSYNC flag on (and the SDL_Delay(0) before outputting audio), everything is perfect. No skips on the sound. I'm not sure I understand at this point why this is so. I had fixed the audio ring so that in case of underrun it emits the last sample, so perhaps that is why.
The audio should rather be output at given cycle intervals, so the wait should be rather tied to elapsed cycles: every 1820 cycles it should do this wait. This way even if the kernel changes or is goofed up the emulator keeps going. Or even if someone decides to process audio twice, outputting a second time mid-line to get ~31KHz. You could even ask a more sane (such as 48KHz) audio sampling rate from SDL then, and tune the elapsed cycles accordingly (597 cycles then).
Hmmm...interesting. So you mean a separate audio thread mixing at 22Khz and interpolating sample? It would pick the sample as you said at a regular 1820 uzem cycles. Didn't fully thought it up, but yeah, that could do it. :)
Mine jumps to 73 MHz with no sound. Without sound enabled, there is nothing limiting the speed of the emulator, so it runs it as fast as your computer can run it. Adding the VSYNC flag back makes it run at the correct speed with no sound, because then it blocks on the call to SDL_RenderPresent.

My vote is for 48 KHz, since that's what sound cards use internally, and that should prevent any additional resampling which might impact the audio quality and it might slow us down if SDL is what ends up doing the resampling.

User avatar
Jubatian
Posts: 1355
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Real-time syncing the emu - why by video?

Post by Jubatian » Mon Oct 05, 2015 6:45 pm

I read the other topics (SDL2 porting) and I see there is an "incentive" to go back to have a possibility of sync by video, lured in by nice smooth scrolls.

Maybe sounds crazy, but what about both at once?

I was toying with this thought with my own emulator project, and I feel it might be possible, although definitely not on a permanently on basis, just as a feature. Video might be the tougher part, since you can only sync to vsync, and have no info between two vsyncs. With sound, you can measure the lag more precisely by how full your audio buffer is. If the program syncs to video, and it is about 60Hz all right, then in the long run, by monitoring the audio buffer's load, it could be possible to manage the audio output rate to align with video.

The simplest it is to imagine by that, say, the emulator starts with 15734Hz as normal, and outputs samples with this rate. If it experiences that the buffer is draining, it increases the rate slightly, say, to 15770Hz, hoping it can catch on. If it experiences that the buffer becomes ever longer, then does the opposite, reducing the rate to, say, 15700Hz. Of course not in such a crude manner, the point is that the program should slowly discover the true skew between video and audio, and play the latter with very little fluctuation in output rate.

Just an idea, I think this shouldn't be attempted right now, for now lets just get the emulator working well. The change to 48KHz, and removing the kernel dependency is something which should be done, I think, as soon as possible (it also even eases a bit kernel development without real HW). If playing back 15734Hz at 48KHz, I don't even think interpolation is that much necessary, just spit out the samples when they come. Most will span 3 48KHz samples with an occasional 4, I don't think that would be anything really audible. Basically write_io just sets the sample value, then when the 48KHz buffer needs it by elapsed cycles, update_hardware pushes whatever is on the port (PWM output) into the audio output puffer. So it becomes completely independent of how the kernel is coded (or does it even output at all). This type of solution makes it easier to implement changing the elapsed cycles later, so even the above idea may be built on top of it.

Post Reply

Who is online

Users browsing this forum: No registered users and 25 guests