irixxxx / picodrive

Fast MegaDrive/MegaCD/32X emulator
Other
52 stars 24 forks source link

regression: clipping like distortion with ring sound in Sonic3 #93

Closed notaz closed 1 year ago

notaz commented 1 year ago

This is better audible with filtering off (although I can hear it with it on too). I haven't investigated it, but in cheat menu (with music off) the ring sound doesn't distort, so perhaps it's actually clipping. Definitely not an issue in 1.93.

irixxxx commented 1 year ago

Hmm. I increased the volume from 6/8 to 7/8 of the computed sample since I had reports that for some devices it was too low. You could change pico/sound/mix.c line 18 back to val >> 2 to check if this is the reason. (val >> 2) - (val >> 4)would be something like 6.5/8, that might be a viable compromise.

irixxxx commented 1 year ago

No, it's not clipping. I have added a debug output in case it clips, and that never comes. What are your exact sound settings? On which platform and with which sound driver?

notaz commented 1 year ago

Right, it already comes like that from ym2612. I did a git sect and 134092feb7ea612db0a74c547667978aab980595 came out. Double checked, it's definitely it.

notaz commented 1 year ago

Narrowed it further to this:

// one line has 488 68K cycles and 228 Z80 cycles, 228/488*8192=3827
#define cycles_68k_to_z80(x) ((x) * 3822 >> 13)  // good sound
//#define cycles_68k_to_z80(x) ((x) * 3847 >> 13)  // bad sound

BTW that comment isn't entirely correct, the master clock is divided by 7 for m68k and 15 for z80, so the real ratio should be 7/15 and not 228/488, which means the correct multiplier is 3822 (or maybe 3823) which is what I originally had there. The difference probably comes from the fact that one of the 262/313 lines is supposedly incomplete. People at spritesminds call it half-line IIRC.

The cause of OD2 problems is clearly somewhere else, perhaps ym2612 timer or not emulating the half-line or something.

notaz commented 1 year ago

The cause of OD2 problems is clearly somewhere else, perhaps ym2612 timer

Indeed if you speed the timer A twice, OD2 audio goes back in sync without needing to overclock z80. If you slow it the whole soundtrack funnily slows down accordingly. So we might have problems with timers. Or at least it's a much better place to place the hack in IMO.

irixxxx commented 1 year ago

It's something like 3822.9, so more on the 3823 side. Yes, computing 288/488 is off by about 0.1%. I recomputed this when I found out that sound is too slow for OD2, but I agree it's wrong. It's an ugly and abominable hack.

I totally forgot about that half line. I need to refresh my knowledge about those ancient TV standards. Shame on me, I actually taught myself to fix TVs in the 90s and had that knowledge back then. It's of course 525 lines for a full NTSC frame and 625 for PAL, so 262.5 and 312.5 for a field. That should definitely be taken into account for the timing!

I never looked in-depth into the ym timer code. I had the impressions it's rarely used since it can't generate interrupts and I had difficulties finding real usage examples. Before I write one myself, you know if there's some code testing this somewhere?

And now that you say it, there's sound missing in the OD2 piloting scene. There's probably a bug in the ssg implementation. I'll try to track that down.

irixxxx commented 1 year ago

I think I found a part of the wrong ssg sound - please enable the recalc_volout in ym2612.c:883 and see if it sounds more like you think it should. I originally thought it's not necessary since it's recalculated in the eg phase anyway. That's however only executed every 3 ticks, whereas the ssg updates are executed every tick. It at least sounds different now even to me and my not exactly good hearing.

notaz commented 1 year ago

It does change the output dumps but I can't seem to hear any difference.

About timer tests, I don't know or have any. But maybe I can come up with something sometime later.

irixxxx commented 1 year ago

Since I have no good hearing of higher frequencies I normally record the audio and play it at half speed with audacity. That also allows to view the frequency spectrum of the signal. I can hear a difference there, and it's also visible in the spectrum, albeit only at higher frequencies. Bo idea though if there are scenarios where this is actually noticeable at lower frequencies.

irixxxx commented 1 year ago

I discovered a discrepancy between the C and ARM variants, and additionally adapted both to recalculate audio in certain situations. Recordings aren't sample identical, but the spectrum representation of audacity now shows nearly identical spectra for both. In with f3876af. Besides, this possibly explain why I actually heard a difference where you didn't, since I used the ARM version for my tests. It definitely produced wrong audio for a certain SSG situation.

irixxxx commented 1 year ago

@notaz have you tried running OD2 either with FM filtering enabled, or, if that works for you, at native rate? Is it still sounding incorrect to you?

irixxxx commented 1 year ago

Over the last days I revisited the z80 cycle timing and 68k bus access:

I also revisited the ym2612 timer implementation. It's now free of all those magic numbers and uses the cycle macro to compute those numbers. That delivers much more accurate results.

It now seems to work much better with OD2. Only a small adaption to the timing of the timers is needed to align the audio and video.

Could you please check if this works better for you with the ring sound in Sonic 3?

notaz commented 1 year ago

Yes Sonic 3 distortion is gone, and nothing stands out for me in OD2 any more. Good work!

irixxxx commented 1 year ago

Oh, I thank you for the tip with the ym timers. That saved some time for sure!

For the record: fixed with f3876af, e0c4dac, and c3d70d1.

irixxxx commented 1 year ago

FYI, I had a look at what games actually use the YM2612 timers and was really baffled at how widespread it is. Guess I'll change the implementation slightly to improve accuracy in a way that the OD2 adaption has less impact on other stuff.