|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Author | Message |
---|---|
|
Choppy sound
Posted: Mon May 09, 2005 9:28 pm
|
I've been going over the sound routines looking to improve the periodic choppiness of the sound. The sound issues show up in the logged WAV files, so I don't think it's driver related. I've been playing with Kega Fusion and the sound support there is far cleaner, but I'd rather work towards improving Meka.
I see there are some comments in the source about "crappy routines" and gaps. Maybe you can elaborate on your experiences to help me find the root cause of the problem? |
|
|
Posted: Mon May 09, 2005 9:57 pm |
Hello Rob,
I just finished typing something and closed my browser. Argh. Again, with less motivation. Referring to TODO.TXT: - Screwed sound.
That is the WORSE problem ever. The problem is that buffer is filled asynchneously, called by an Allegro timer. The buffer-filler looks for the current cycle to know where to stop filling, but this is running in emulation which is not in sync with the timer. As a result, depending on luck/computer, sometimes the buffer gets overflowed, and sometimes it doesn't fill up to the end! That's the cause of sound scratches. Can be fixed by 'merging' sound/video sync timers but that would require removing unthrotled emulation. MAME supports sonud while unthrottled but it requires lots of work. It's actually not a lot of work to do the standard thing... Must do it... The problem in itself is not very difficult to fix. Removing unthrottled emulation makes everything easier to fix. It bring another problem which is that currently unthrolled emulation manage to skip frames sometimes before of the crapness of the code. So basically, the proper way would be fixing both at once. - Remove unthrottled emulation. Stick to throttled emulation, so that the program KNOWS how many frames will be emulated this second (50/60 usually, but it can be anything). - Remove allegro timer callbacks used by video/framecounter/sound. - Setup a pollable timer. Allegro cannot do that, so have to use OS-dependant code (eg: timeGetTime() under windows). - Mainloop must poll this timer to advance emulated frame. Proper code should make it that exact X frames must be emulated and drawn per 1000 ms. Using a floating point counter or catching up with leftover could do it, waiting 1000/X ms per emulated frame would not, because of rounding issues (1000/60 = 16.66). (That is why currently MEKA in throttled 60 hz mode with vsync skip frame, because the callback is set to call every 1000/60 and there's no catchup. MEKA works best in 1/1 with vsync and video mode set to 60 hz). - Mainloop in charge of calling 1. polling timer 2. calling emulation, 3. video refresh at end of frame 3. sound filling at end of frame. Mid-frame, emulation must be able to call sound emulation fill the sound buffer up to a certain point (just before changing sound registers). The certain point in question should be computed based on known length of this frame in milliseconds, which becomes number of sound samples (based on sound output frequency), and current cycle / frame total cycles. Current cycle is current line * iperiod + iperiod - count, or something like that. The above sentences are probably criptic but it should make sense, it's fairly logical. There's many little side points to be worked out but this would be the main part. Basically: remove callbacks, rely on a single polled timer so we know exactly where we are. Honnestly, I think this work may not be easy to do for you or another person since it involve modifying several different places in MEKA. I could possibly get a basic working thing and leave it to actual thinking people to fix possible corruption/sample skipping I'll get in a new version of the system. |
|
|
Posted: Wed May 11, 2005 5:10 pm |
Thanks. Your description helps greatly and makes perfect sense. I'm still going over the various routines getting familiar with the various processes and what they are doing.
You also have the issue of synchronizing to the sound card's clock. Seal doesn't help us in this regard (the buffer fill callback is for *internal use only*... grrr), With multimedia, it's actually common to use the sound card as the primary clock, and synchronize everything else to it (a frame skipped or doubled here and there isn't as noticeable as a sound buffer over/underrun). The other option is to stretch or compress the sound buffer to keep it in tme with the buffer. A slight pitch shift isn't that audible and is preferable to "scratching". If we're able to pro-actively monitor the output buffer levels, we could just tweak the sampling frequency to ensure that the sound card's buffer level stays where it should. You could potentially create interesting effects with that too - if you "fast forward" the emulation, the sound could speed up along with it, like an audio tape. :) |
|
|
Posted: Thu May 12, 2005 5:17 pm |
I implemented syncing the emulator speed to the sound card's clock. I simply removed the Allegro timer, moved the sound update routine to where the vblank is handled, and added code to wait for the sound buffer to be available. That works very well. I also disable the other throttling done in the Allegro timer. This of course locks the framerate to DEF_SOUND_BASE. If we implement this option as a real feature we'd need to turn that into a variable and have it reinitialize the sound for 50hz for PAL.
The problem now is syncing the video. Two throttles (waiting for the sound to be available, then waiting for the video to be available) do not play together nicely at all. So, I am looking at adding triple buffering support to the video. That should allow us to keep the emulation synced to the sound card and have vsync without getting too messy. I'm sure I'm breaking a million things in the process, but I'm going for a proof-of-concept right now. :) *Edit* Well, geeze, that was easy. I think I like this Allegro library. So far it works beautifully! Nicely synced video and no more choppy audio. I added a little more granularity to DEF_SOUND_BASE so I can set the refresh rate to 59.8fps. The result is better when you keep the sound behind the video, or else the video system waits for a frame to clear, pausing the sound. If the sound is just a tad slow the user simply gets a double-frame once in a great while. |
|
|
Here is the new version of my modified Meka
Posted: Thu May 12, 2005 10:00 pm
|
http://www.tvrules.net/misc/mekahq2x.zip
I have also fixed the Game Gear hq2x/scale problem as well as synchronizing the palette before the 16 bit conversion. The included config files are set up for hq2x / 1024x768 / triple buffering / sync to audio. If audio still skips for you try lowering the sync_to_audio variable in mekaw.cfg. |
|
|
Posted: Fri May 13, 2005 12:09 am |
Thanks greatly, this is amazing. I gave it a quick try and it sounded ok.
Aren't some sources files missing or not up to date from your ZIP file? (the patch is suspisciously very small :) I'll work on implementing those stuff, but as you pointed out, there's some decent amount of work needed to use this in the release version. Also need to rework a few things on the support/software side (namely, keyboard repetition and double-click are broken now, and handling different speed will be required). |
|
|
Posted: Fri May 13, 2005 1:29 am |
Oops. Forgot to add the sound subdir. :) I've uploaded a new zip. I have tested that lowering the sync_to_audio variable to 500 causes the emulator to run at 50hz, and it is still compatible with the triple buffering. You just need to reinitialize the buffer with the new rate. I don't really run anything at 50hz and I figure you know the proper places to do that.
Not sure why the keyboard became affected by it, but I can't test that on my dev machine. My DirectInput is broken and I have not been in the mood to do a full OS reinstall to fix it. Fortunately Meka still starts and runs enough for me to hear audio and watch as game demos play. *Edit* Ahh .. that's an easy one - the keyboard works fine as long as there's sound playing. No sound = no throttle. Can probably add an if clause into the throttler to let it work while there's no sound to fix that. Alternatively you can just enable vsync in the gui. My config file has it disabled because it seems to cause crashes on my game machine. I put it back on as default in the most recent zip file, and fixed a stupid triple buffer bug in video.c. -- Rob |
|
|
Posted: Fri May 13, 2005 4:26 pm |
The zip is broken, I think. | |
|
Posted: Sat May 14, 2005 3:54 pm |
Re-upped. | |
|
Posted: Sun May 15, 2005 7:59 am |
cc -I. -I./tools -I./sound -Ilibs -I../include -I/home/jsikorski/downloads/seal-1.07/include -DUNIX -DX86_ASM -DMEKA_SOUND -DMEKA_EAGLE -DMEKA_ZIP -DMEKA_PNG -DMEKA_JOY -DMEKA_Z80_DEBUGGER -Wall -march=pentium4 -O3 -ffast-math -fno-strength-reduce -funroll-all-loops -DMARAT_Z80 -c meka.c -oobj/meka.o
meka.c:24:21: options.h: No such file or directory meka.c:28:22: tileview.h: No such file or directory meka.c: In function `Init_Default_Values': meka.c:177: warning: implicit declaration of function `TileViewer_Init_Values' meka.c: In function `main': meka.c:353: warning: implicit declaration of function `Inputs_Init' meka.c:363: warning: implicit declaration of function `Init_Joystick' make: *** [obj/meka.o] Error 1 [jsikorski@DOMOWY srcs]$ Compiling under linux. I guess I have to install some library, but which one? |
|
|
Posted: Sun May 15, 2005 10:04 am |
This was fixed in the latest WIP versions. Use them instead of 0.70. (In case you want to apply DjRobx patch over the WIP version, you'll have to generate a diff file between his files and 0.70 then apply it over latest WIP and compile WIP). |
|
|
Posted: Sun May 15, 2005 11:21 am |
Is there any quicker way to do this thas diff -Nru each file? I'm not familiar with generating diffs of a whole directory :(
[edit] I've managed to go further, Kompare and some manual edits were useful. But I get htis error at hte end of compilation process: obj/meka.o(.text+0x4ce): In function `Init_Allegro':
: undefined reference to `Blit_HQ2x_InitLUTs' obj/blit.o(.text+0xaa0): In function `Blit_Fullscreen_HQ2X': : undefined reference to `hq2x_16' collect2: ld returned 1 exit status make: *** [../meka.exe] Error 1 [jsikorski@DOMOWY srcs]$ I guess that hq2x16.asm and hqfilters.c should be added to makefile somehow. I have not figure the muthod yes, though. |
|
|
Posted: Sun May 15, 2005 1:39 pm |
Yes. Check the line starting with "OBJ_VIDEO =" and add both object file names at the end (hq2x16.o and hqfilters.o). May need to tweak symbols in the .asm files, to add or remove underscores, if it doesn't link. I'm curious to know if you get correct sound on this version, when you build it. |
|
|
Posted: Mon May 16, 2005 6:27 am |
Sorry to bother you, but still got some problems here:
make: *** No rules for making`obj/hqfilters.o', required by `../meka.exe'. Stop.
[jsikorski@DOMOWY srcs]$ There also some problems with assembling hq2x.a6.asm (hq2x16.asm:1802: error: short jump is out of range ), but I've solved it by adding -O1 to the command line, as it it done in vcproj file. Greets. Also invoking the gcc manually returns the following: [jsikorski@DOMOWY srcs]$ cc -I. -I./tools -I./sound -Ilibs -I../include -I/home/jsikorski/downloads/seal-1.07/include -DUNIX -DX86_ASM -DMEKA_SOUND -DMEKA_EAGLE -DMEKA_ZIP -DMEKA_PNG -DMEKA_JOY -DMEKA_Z80_DEBUGGER -Wall -march=prescott -O3 -ffast-math -fno-strength-reduce -funroll-all-loops -DMARAT_Z80 -c hqfilters.c -oobj/hqfilters.o
hqfilters.c:1:21: windows.h: No such file or directory In file included from hqfilters.c:2: blit.h:53: error: syntax error before '*' token blit.h:53: warning: type defaults to `int' in declaration of `Work_Line' blit.h:53: warning: data definition has no type or storage class hqfilters.c:8: error: syntax error before "DWORD" hqfilters.c: In function `Blit_HQ2x_InitLUTs': hqfilters.c:40: error: syntax error before '{' token hqfilters.c:21: warning: unused variable `nMMXsupport' hqfilters.c:45: warning: no return statement in function returning non-void [jsikorski@DOMOWY srcs]$ |
|
|
Posted: Mon May 16, 2005 6:44 am |
Default Makefile rules requires a .h along with the .c. Create an empty hqfilters.h that should be enough for the moment.
I guess... remove the windows.h include. Replace by: #include "shared.h"
Bear in mind that I have not even compiled this code yet so I'm guessing. But it's fairly obvious that windows.h must be included in a GNU/Linux build, and it's hardcoded in hqfilters.c right now. |
|
|
Posted: Mon May 16, 2005 7:02 am |
[jsikorski@DOMOWY srcs]$ make
cc -I. -I./tools -I./sound -Ilibs -I../include -I/home/jsikorski/downloads/seal-1.07/include -DUNIX -DX86_ASM -DMEKA_SOUND -DMEKA_EAGLE -DMEKA_ZIP -DMEKA_PNG -DMEKA_JOY -DMEKA_Z80_DEBUGGER -Wall -march=prescott -O3 -ffast-math -fno-strength-reduce -funroll-all-loops -DMARAT_Z80 -c hqfilters.c -oobj/hqfilters.o hqfilters.c: In function `Blit_HQ2x_InitLUTs': hqfilters.c:40: error: syntax error before '{' token hqfilters.c:21: warning: unused variable `nMMXsupport' hqfilters.c:45: warning: no return statement in function returning non-void make: *** [obj/hqfilters.o] Error 1 [jsikorski@DOMOWY srcs]$ I guess assembler is introdused improperly here. |
|
|
Posted: Mon May 16, 2005 7:41 am |
Yes, the assembler syntax used is not portable. Comment it and return 0, as the function return is not even retrieved by the caller right now. I'll switch it (when I integrate the code) to use the already detected MMX support flag and need to see if HQ2x has MMX and non-MMX versions. I guess almost everyone has MMX now, so I could just disable HQ2x without MMX, in the worse case. |
|
|
Posted: Mon May 16, 2005 5:40 pm |
I've succeded in compiling. some %DEFINEs were required to allow linking. The sound works ok. But the hq2x filter really sucks. It's probably OS-dependent issue. Have a look:
|
|
|
Posted: Mon May 16, 2005 5:42 pm |
Not sure about the filter, but we'll work it out somehow. Sound working right on GNU/Linux is a great new however. No slutter, delay? How does standard MEKA 0.70 sound on the same computer? |
|
|
Posted: Mon May 16, 2005 5:53 pm |
The sound of 0.71 WIP is as good as this version. Maybe I can't see the difference because of crappy soundcard (I have Realtek AC'97). There were some serious problems up to mekanix 0.69 and Mandrake, it was just hanging the system. I have Fedora Core 3 now and self compiled both seal and meka. Maybe that's why it works flawlessly.
[edit] mekanix 0.70 still hangs system here. To be more exact, selecting linux voxware as soundcard causes massive cpu overload. |
|
|
Posted: Mon May 16, 2005 6:20 pm |
This could possibly be the very same reason mine doesn't work. I'll have to try Redhat out. I have been toying with mine for a good month now and still cant sound to work properly, locks up the system almost everytime with my crappy AC'97 card :) Once I get this issue worked out I would be happy to help test this on Linux. :) |
|
|
Posted: Mon May 16, 2005 6:44 pm |
I've had SB 128 PCI when I used mandrake. Instead of reinstalling the system, try compiling the latest wip source using the suggestions from this forum. | |
|
Posted: Tue May 17, 2005 1:15 am |
I have a crappy AD1985 AC97 on Realtek drivers. It's mostly a timing dependent thing. Sometimes the 0.71WIP sounded just fine, other times it would break up badly. As Bock noted, it is somewhat system dependent. It also seemed to be more obvious is some games than others (it would scratch a lot in Wonder Boy In Monster Land, for example). I have sensitive ears though.
That HQ2X image looks almost like there's an endian or variable typing problem or something. It's interesting because it is upscaling, it's just inverting pixels in both directions (horizontal and veritcal). There is a C version of the hq2x filter available on the author's site. You might try that. The other possibility is that your 16bpp mode isn't RGB565. There are actually some different implementations of 16 bits per pixel, and I think HQ2X assumes RGB565. Does hq2x work in Zsnes under Linux? If it does, you might have a look at their sources to see what compiler options and such they are using (and their Blit_HQ2x_InitLUTs function). |
|
|
Posted: Tue May 17, 2005 6:40 am |
It works with zsnes, as well as with wba and gens. | |
|
About the sound
Posted: Tue May 17, 2005 6:52 pm
|
Mister Jim Larimore, super tester, who had problem with Mekaw, said:
Just quoting for you to know. I'm not commenting on it now because I haven't given the time yet to work on this code at all. I think that I'll integrate the 16-bit/stretch/hq2x part for version 0.71, and may focus on making 0.72 the version with definitive sync and sound fixed. This part will require much testing and some support code. |
|
|
Posted: Tue May 17, 2005 7:24 pm |
An idea apperared in my mind that my problem with hq2x may be a result of 24 bit depth? my destkop is configured to 1600x1200x24. I don't know why, but x.org does not support 32 bit, at least for nvidia cards. Greets. | |
|
Posted: Tue May 17, 2005 7:50 pm |
Right now the buffer is converted to 16-bit, then Allegro and/or X-Window would convert it to your native depth. I'm not sure where the problem lies, but anyway, both 16 and 32 bits should be supported (right now it's only 16-bits).
Maybe it's scale related? (Allegro scale could be buggy in certain cases) |
|
|
Posted: Tue May 17, 2005 10:10 pm |
HQ2X, as I implemented it, only supports 16 bits per pixel. There's a 32bpp .asm file but it is not used. Definitely try removing the stretch option from meka.blt, Allegro uses extremely funky self-modifying code to peform a stretch. | |
|
Posted: Wed May 18, 2005 4:26 pm |
The stretch option does not matter here. My meka.blt:
--cut--
[Fullscreen::UNIX] res = 640x480 blitter = hq2x driver = auto [Windowed::UNIX] res = 256x200 driver = auto_win [Windowed Double::UNIX] res = 512x400 blitter = hq2x driver = auto_win [edit] The hq2x works fine also with nintencer http://nintencer.fobby.net, a NES emulator derived from abandoned FCE ultra. |
|
|
Posted: Fri Aug 18, 2006 3:41 pm |
Can anyone confirm that the choppy sound issue has been fixed in Meka 0.71, since I am experiencing this problem on my Dell PC. If not, will it be fixed in Meka 0.72? | |
|
Posted: Fri Aug 18, 2006 4:45 pm |
I'll try to have it fixed whenever possible. Sorry sorry. ;( | |
|
Posted: Thu Aug 31, 2006 7:00 pm |
Well here is a HQ2X setting for meka I changed the default one in a erlier release of meka and seemed to fixed the HQ2X problem, cause my old Nvidea GEforce 2 MX graphics card was having problems with the default setting.
Like screwed up display or bad graphics but that's now fixed Orignal [HQ2X::WIN] res = 1024x768 driver = directx refresh_rate = auto blitter = hq2x video_depth = 16 triple_buffering stretch New [HQ2X::WIN] res = 1024x768 driver = directx refresh_rate = 75 blitter = hq2x video_depth = 16 triple_buffering stretch So it seems to me that it might be a refresh rate problem. |
|