Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PCM audio produces buzzing note in many games. #143

Closed
SegaSnatcher opened this issue Feb 6, 2021 · 15 comments
Closed

PCM audio produces buzzing note in many games. #143

SegaSnatcher opened this issue Feb 6, 2021 · 15 comments

Comments

@SegaSnatcher
Copy link
Contributor

SegaSnatcher commented Feb 6, 2021

There appears to be a bug in the PCM audio. Many games are hit with this bug.

Here are a few examples I tested.

10-Pin Bowling

https://www.youtube.com/watch?v=KLoAIqOF1ss

3D Pocket Pool

https://www.youtube.com/watch?v=Yr2qe2zI5hs

Army Men

https://www.youtube.com/watch?v=6wSICCztpSo

Vigilante 8

https://www.youtube.com/watch?v=60acUR3KnmU

Here is the full list of GB/GBC games that use PCM audio in some way. I'm sure more games have this same issue.

https://chipmusic.org/forums/topic/16824/incomplete-list-of-gbgbc-games-to-use-pcm-samples/

@SegaSnatcher SegaSnatcher changed the title [GBC] Vigilante 8 produces constant high pitched note during intro music and when you shoot in game. PCM audio produces buzzing note in many games. Feb 6, 2021
@lhathcock
Copy link

lhathcock commented Dec 29, 2021

I tried Vigilante 8 and 10-Pin Bowling on my GBA SP and original GBA with an EverDrive X3, and got the same audio corruption. I don't have an actual GBC to compare to. Anyone have a GBC to check this?

EDIT: Looking around, many of these games have audio problems on GBA vs. GBC, which means something the GBC core is behaving more like the GBC implementation in GBA hardware.

@SegaSnatcher
Copy link
Contributor Author

I tried Vigilante 8 and 10-Pin Bowling on my GBA SP and original GBA with an EverDrive X3, and got the same audio corruption. I don't have an actual GBC to compare to. Anyone have a GBC to check this?

EDIT: Looking around, many of these games have audio problems on GBA vs. GBC, which means something the GBC core is behaving more like the GBC implementation in GBA hardware.

Nice catch I can confirm using my IPS modded GBA. This core is handling those sounds more like a GBA handles GBC playback than native Gameboy Color hardware.

@maij
Copy link
Contributor

maij commented Nov 2, 2022

I think this might have the same root cause as #102. It's not an issue with PCM per se but the implementation of the wave channel, I suspect.

@SegaSnatcher
Copy link
Contributor Author

I think this might have the same root cause as #102. It's not an issue with PCM per se but the implementation of the wave channel, I suspect.

Good work on fixing those other audio issues! Crossing fingers you might be able to solve this issue as well.

@paulb-nl
Copy link
Collaborator

I think I found what's causing this. Currently the core always outputs 0 as the first sample when the wave channel starts playing which is not correct.

I will work on improving the sample reading implementation.

@dfilskov
Copy link

Great :)

@maij
Copy link
Contributor

maij commented Nov 24, 2022

I did have a look at the suppressed values (setting them to 0100 instead of 0000) at one point while debugging the other issue. When I combined the latest changes with the suppressed value change it broke the PCM sampled audio in those other games. But maybe you have a clearer idea of how to fix this! Looking forward to it.

It's curious this isn't a problem for the other channels, which also have suppressed values. I thought it might be APU wav table collisions with the cpu, but couldn't identify where that error is introduced..

@paulb-nl
Copy link
Collaborator

Pan docs says triggering the wave channel makes it play back the last read sample as the first value so outputting 0 for the first sample is incorrect. I have implemented this but this hasn't fixed it.
https://gbdev.io/pandocs/Audio_Registers.html#ff1e--nr34-channel-3-wavelength-high--control

The game Tarzan disables the wave channel DAC every 1/256th of a second to update the wave pattern. The core currently outputs 0 (highest voltage) while the DAC is disabled and this coincides with the buzzing pulses.

Pan docs says that when a channel DAC is disabled the voltage fades to 0 volt. This must be what prevents the quick voltage change which causes the buzzing noise. This also explains why the GBA has the same buzzing sound because it does not have DACs per channel and does mixing digitally.
https://gbdev.io/pandocs/Audio_details.html#dacs

It appears that a slow transition to 0 volt needs to be implemented when a DAC is disabled.

@dfilskov
Copy link

dfilskov commented Nov 25, 2022

Good work, though.

Hmm, can we analyze a recording of the game on a real Game boy and compare it or are you quite sure how the fix should work?

@maij
Copy link
Contributor

maij commented Nov 25, 2022

Pan docs says triggering the wave channel makes it play back the last read sample as the first value so outputting 0 for the first sample is incorrect. I have implemented this but this hasn't fixed it. https://gbdev.io/pandocs/Audio_Registers.html#ff1e--nr34-channel-3-wavelength-high--control

I thought the wav_wav_r already took care of this? Don't have the code in front of me to check.

The game Tarzan disables the wave channel DAC every 1/256th of a second to update the wave pattern. The core currently outputs 0 (highest voltage) while the DAC is disabled and this coincides with the buzzing pulses.

Interesting, I wonder why it did that since you can update the wav table on the fly in CGB mode, and Tarzan is a CGB only game.
It's worth noting that this noise issue is prevalent for DMG only roms as well, like the sound test rom. That would make sense with disabling/enabling the wav channel, or turning the DAC off, since you can't write to the wav table while it's playing. I guess I was wrong about cpu/APU wav table collisions.

Pan docs says that when a channel DAC is disabled the voltage fades to 0 volt. This must be what prevents the quick voltage change which causes the buzzing noise. This also explains why the GBA has the same buzzing sound because it does not have DACs per channel and does mixing digitally. https://gbdev.io/pandocs/Audio_details.html#dacs

It appears that a slow transition to 0 volt needs to be implemented when a DAC is disabled.

This decay to 0 is already implemented, the mister sys has a high pass filter at the output. May be worth double checking?

My mixer output implementation converts 0000 to 1000 (signed) for each channel output, so if each channel outputs 0000 when its off that should technically be wrong, it's definitely the most... But I can't make sense of why it e.g. Produces ringing in the square waves and doesn't fix this noise issue. Have you seen this issue as well? I'm suspicious of the envelope counters.

N.B. It really shouldn't matter, but technically the code 0000 should be the most positive voltage and 1111 the most negative. My implementation is the opposite, but sign shouldn't matter here.

Thanks for looking into this, I have to take some time off from building and testing.

@paulb-nl
Copy link
Collaborator

Hmm, can we analyze a recording of the game on a real Game boy and compare it or are you quite sure how the fix should work?

It's always good to have recordings from a real device.

I thought the wav_wav_r already took care of this? Don't have the code in front of me to check.

wav_wav_r was only updated when the channel was triggered and was forced to 0 when it started playing. Now wav_wav_r is used as the sample buffer and updated every time the wave index is incremented.

Interesting, I wonder why it did that since you can update the wav table on the fly in CGB mode, and Tarzan is a CGB only game.

I don't think you can update the wave table on the fly for CGB. When the wave channel is playing it is in control of the wave address so writes to FF30-FF3F will end up on which ever address the wave channel is currently playing from.

This decay to 0 is already implemented, the mister sys has a high pass filter at the output. May be worth double checking?

Yes you are right. Now when the Wave channel DAC is turned off I just keep outputting the value from the wav_wav_r buffer and when I record the analog output I see it going to 0 volt in the waveform.

But I can't make sense of why it e.g. Produces ringing in the square waves and doesn't fix this noise issue. Have you seen this issue as well?

No idea about that.

Here is a build with the changes which now plays the PCM sound without the buzzing. It would be good if people test this for regressions.
Gameboy_pcm_20221126.zip

@maij
Copy link
Contributor

maij commented Nov 26, 2022

Nice! I've tested a couple of roms that had the wav noise and it seems to have been the key fix. Haven't done any regression tests yet but will get back to you. Are you on discord, you could post the test build to the mister community. If not, I could do so on your behalf.

wav_wav_r was only updated when the channel was triggered and was forced to 0 when it started playing. Now wav_wav_r is used as the sample buffer and updated every time the wave index is incremented.

Huh, that seems like a simple fix. Based on the documentation about the APU they do say every wave sample is buffered, so this would be a more faithful implementation (I find the way gbc_snd,.vhd is written very terse and unclear, it might be good to rewrite some of these basic sections like consistent sample buffering.)

I don't think you can update the wave table on the fly for CGB. When the wave channel is playing it is in control of the wave address so writes to FF30-FF3F will end up on which ever address the wave channel is currently playing from.

I think I misinterpreted what was written on pandocs, for some reason I thought the wav access was happening at a slower clock rate and there could be cpu cycles where you could write without issues. That appears to be wrong though.

@paulb-nl
Copy link
Collaborator

I am not on Discord so you can post the build if you want. Here are the source changes: https://github.com/paulb-nl/Gameboy_MiSTer/commits/dmg_mode

@silverflat
Copy link

silverflat commented Dec 7, 2022

I have this bug with Pocket Music which can be seen here:
https://www.youtube.com/watch?v=oo5Ig2Wx71Y

It happens when any of the samples are played. Worth noting that this game is only playable on a Gameboy Color, and will not play on a Gameboy Advance

Your build gets rid of the high pitched buzz and allows the samples to be heard as shown here:
https://www.youtube.com/watch?v=ZJKAiHThaOo

Nice work on this!

@paulb-nl
Copy link
Collaborator

paulb-nl commented Jan 2, 2023

Fixed in release 20230102 with a6f94d6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants