ekeeke / Genesis-Plus-GX

An enhanced port of Genesis Plus - accurate & portable Sega 8/16 bit emulator
Other
701 stars 202 forks source link

Sound emulation issues #71

Closed Reinc01 closed 8 years ago

Reinc01 commented 8 years ago

Echoing, rumbling sounds are emulated as a high-pitched noise. Can be heard in some explosions in various games. Most noticable in the game Dune: The Battle for Arrakis. Atreides' Sonic Tanks are supposed to shoot with a sound that resembles the sound of boiling, whereas the emulator produces a whistling sound.

ekeeke commented 8 years ago

If you are using the Wii (or Gamecube) version make sure FM emulation is set to High-Quality and try to enable the Low-Pass filter (in sound options). In libretro version, the Low-Pass filter is disabled by default so it might explain these high-pitched vs muffled sounds you are hearing.

There is no code that specifically deals with "echoing" or "rumbling" sound, FM emulation does not work like that and potential inaccuracies would therefore be limited to some edge cases in some specific games. If you want me to check if these are really emulation inaccuracies, I will need specific examples in several specific games. I have also no idea what "Atreides Sonic Tanks" are or how/when/where they can be heared so ideally, specific sound in an accessible sound test is preferred to investigate and compare emulation with real hardware. If not possible, at least giving as much details as possible to help me reproducing your issue is required.

Reinc01 commented 8 years ago

I'm actually using the PC version from the Bizhawk emulator. They use your core. Is my issue supposed to be posted here? I will provide details on the issue if it is.

ekeeke commented 8 years ago

Is my issue supposed to be posted here?

Sure, if you think this is a core issue, there is no harm posting here so it can be confirmed.

In the mean time, you can also ask Bizhawk dev to enable low-pass filter or make it configurable.

Wherever this is done in Bizhawk port, the following code

config.filter= 0;

should be changed to

config.filter= 1;

to enable low-pass filter on audio output (similar to what real megadrives were doing). Cut-off frequency depends on console models so filter ratio can be configured by config.lp_range setting (default is 60% when enabled).

ekeeke commented 8 years ago

I had to delete your post , please don't upload copyright-infringed material on this repository. Unfortunately, i dont use bizhawk and would prefer to verify the sound on my own core implementation so the savestate is useless to me. If you could make a vidéo , it would be better.

vadosnaprimer commented 8 years ago

to enable low-pass filter on audio output (similar to what real megadrives were doing)

It's surprising to know that it was an actual hardware feature, not an emulator author's hack (that I thought only existed in Gens). If the tests confirm that, it can become default to switch the filter on in bizhawk too.

ekeeke commented 8 years ago

Analog audio amplifiying and filtering circuitry after the output of the digital sound chips is a very common thing in console hardware and this is what makes most of the sound differences between model 1 & later models of Megadrive/Genesis that people generally brag about.

The software implementation of low-pass filtering stage might not be 100% accurate but the default .range value was adjusted to produce similarly muffled sound as my model 1 megadrive. It was made configurable so that people can adjust it to match their own remembered model sound and it can be disabled for people who prefer crystal-clear digital sound.

There is also a fully configurable 3-band equalizer for finer tunings, which can be enabled by setting config.filter to 2.

Reinc01 commented 8 years ago

Here is an archive with a short sound test video. These are the kind of sounds that I remember sounding much softer on real hardware. Dune sounds.zip In case of Sonic Blast sound, you can hear the soft sound playing simultaneously with the high-pitched noise, which I certainly never heard when playing this game on real console. In case of Explosion 1 sound, I only started noticing these kinds of sounds after I started using Mega Drive emulators, I don't remember hearing explosions like this in any game back in the time.

vadosnaprimer commented 8 years ago

I tried with and without it, and I hear zero difference. https://www.dropbox.com/s/h3c0cv6tpbceovp/filter.7z?dl=0

Load ROM -> Genesis -> Settings. Available lowpass range is 0 - 65535. https://www.dropbox.com/s/3p2agitqff88qrd/BizHawk.zip?dl=0

Reinc01 commented 8 years ago

I can hear Exsplosion 1 sound, especially the echo at the end, sounding slightly softer on 65535 compared to 0. Can you increase lowpass range?

vadosnaprimer commented 8 years ago

You mean above 65535? It'd be impossible since it's packed into a short (2 bytes) internally.

ekeeke commented 8 years ago

I just tested these two sounds with this game running on my Mega Drive against same game running on Wii through my emulator with low-pass filter set to 60% (corresponds to range value equal to 0x9999) and they sounded exactly the same.

The high-pitched sounds in background are indeed a little louder in emulator with low-pass disabled but with it enabled, they get a little softer (especially with the Explosion one) and sounds exactly like real hardware. I can confirm a high-pitched drilling sound can be heared in the Sonic Blast sfx on real hardware too.

Note that in the Wii port, FM audio (approx. 53 kHz originally) is resampled to 48 kHz since it's the native Wii samplerate, while libretro and bizhawk set the core audio output rate to 44,1kHz so maybe this can cause some differences when dealing with very high frequencies. Similarly, if you are later resampling the core output to another samplerate for your frontend (I know Retroarch does that for example), this could maybe also introduce some (minor ?) differences. I am no audio processing expert but I would think that logically the less you resample and the closest your ouput rate is to original rate, the less inaccuracies you will get.

rz5 commented 7 years ago

@ekeeke - We're trying to expose the low pass filter as a libretro core option, but we can't hear a difference between no filter and the low pass filter. I personally can hear a difference when we do the 3-band EQ filter, mostly because the volume is greatly reduced.

If we change config.lp_range from 0x9999 to 0x6667, we do notice it. As a test, we're using M.U.S.H.A, and using the sound test menu, specifically sounds 001 and 002.

I also can't hear differences in BizHawk, but the low pass filter option there requires a core reboot. You got any ideas?

ekeeke commented 7 years ago

Enabling low-pass filter should normally be very simple: just set config.filter to 1 and config.lp_range to something between 0 and 65535 (higher is the value, stronger is the filtering). It shouldn't need a reboot either considering nothing needs to be initialized and config.filter is just checked every frame in audio_update().

I have no idea why it wouldn't work for you, 0.6 (0x9999) gives quite noticeable muffled sound in the Wii port. Maybe you missed something when adding libretro core setting or maybe Retroarch is doing something on audio output that cancels or reduces the filtering effect, I don't know (all I know is libretro port output rate is 44100Hz for some reason while Wii port uses 48kHz so same lp_range value might not sound exactly the same between them but not that much). From what I remember, this option was left disabled by default in libretro port because Retroarch had its own audio filters that were likely more suitable and more configurable that this very simple lowpass filter.

@ekeeke - We're trying to expose the low pass filter as a libretro core option, but we can't hear a difference between no filter and the low pass filter. I personally can hear a difference when we do the 3-band EQ filter, mostly because the volume is greatly reduced.

If we change config.lp_range from 0x9999 to 0x6667, we do notice it. As a test, we're using M.U.S.H.A, and using the sound test menu, specifically sounds 001 and 002.

I also can't hear differences in BizHawk, but the low pass filter option there requires a core reboot. You got any ideas?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

rz5 commented 7 years ago

@ekeeke -Hi, thanks for the response.

This libretro core option rework is being done in @hizzlekizzle's fork; config.lp_range is being changed like this: https://github.com/hizzlekizzle/Genesis-Plus-GX/blob/master/libretro/libretro.c#L1042#L1047

var.value takes values between 0.1 and 0.9. What's weird is that:

In theory, 0.9 results in a value of 58982, so the high freq content should be getting filtered out more than 0.4. In practice...totally different. You got any ideas why?

In terms of the libretro port's audio sample rate, I've been asking @twinaphex if it's ok to change the system_av_info's sample rate from 41100 to 48000/53000 but haven't gotten an answer yet. I'll play with that, to see if the sound matches what you're getting on the Wii port.

And finally, while RetroArch CAN have fancy audio filters, it isn't the only libretro frontend out there; since the core can do its own filtering, why not expose it as core options? Also, the users of the libretro forum have been asking for it: https://forums.libretro.com/t/genesis-plus-gx-where-is-the-audio-lowpass-filter/12169/17

ekeeke commented 7 years ago

I am not opposed for this to be exposed, many core settings were not exposed either for the first libretro implementation then got added upon users requests, I was just explaining why it was likely ignored initially. Also, I am not just talking about DSP filters: from what I know, Retroarch (and probably any other libretro frontends) will always resample core audio output to frontend samplerate (this is also where dynamic rate control takes place), surely there is some default filtering taking place here as well. Even if you change the core output rate to something closer to Wii (or even Genesis) native output rate, there will still be this additional resampling stage compared to Wii port.

Sorry but I have no other explanation for what you are describing, the code modifications in libretro.c look fine to me at first glance and if you look at system.c, you can see this is a very simple and straight-forward single-pole low pass filter implementation so there are hardly any bugs here.

ekeeke commented 7 years ago

Looking back at libretro port, I think the issue is that config.lp_range is defined in libretro/osd.h as a signed integer (int16) when it should be an unsigned (uint16 or uint32 if for some reason you want to go up to 100% ie 0x10000). That value is stored into an uint32 variable in system.c so any value above 0x8000 would be treated like a negative value and would likely be sign extended during 32-bit conversion.

https://github.com/ekeeke/Genesis-Plus-GX/search?p=1&q=lp_range&type=&utf8=%E2%9C%93

ekeeke commented 7 years ago

As for EQ gain default values, they shouldn't be set to 1.0 but 100 (these are integer values representing percentage).

rz5 commented 7 years ago

@ekeeke - Regarding the config.lp_range and libretro/osd.h changes: you were right. Making lp_range an unsigned variable fixes the buggy behavior completely, thanks so much for the input. I'll make a PR on @hizzlekizzle's fork and it'll eventually land on the libretro fork too.

In terms of the 3-band EQ option - that one has problems of its own too. I'll invite @Tatsuya79 to write an explanation of the the buggy behavior related to it on here.

Tatsuya79 commented 7 years ago

Hi, the issue with the EQ is as follow: -lg=100 mg=100 hg=100 no problem, sound is the same as standard without EQ -lg=100 mg=100 hg=0 high notes are getting louder, acts as opposite -lg=100 mg=0 hg=0 high notes are muted as intended

mg and hg are inter-dependant. If mg=0, hg works normally, from muted to standard level (probably). If mg=100, hg is higher gain when lowered, starting from standard level at 100. Intermediate mg values act in-between.

ekeeke commented 7 years ago

I never much really used or tested the EQ as it was mostly added after end-user request but now that you are telling it, I see a potential issue with the way it was implemented in system.c: I use same "eq" structure for both left and right channel streams although there is no such thing as stereo support in 3-band code so much likely the filtering is done incorrectly.

ekeeke commented 7 years ago

EQ implementation was fixed in https://github.com/ekeeke/Genesis-Plus-GX/commit/f6f4556533d952fa0504953cc8b503942d4a3a11