Skip to content

Trying to replace NES ghostbusters PCM sample

Technical discussion which is not directly related to VGM files. Talk about Hardware and Software.

Moderator: Staff

  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Trying to replace NES ghostbusters PCM sample

Post by nesrocks »

Hey guys, sorry if this is not the proper forum for this, I'm going crazy! Maybe someone here can help? In general, the hack is being discussed here, but not this particular issue though: http://www.romhacking.net/forum/index.php?topic=24333.0

I've been trying for over a week to replace the Ghostbusters voice sample on the NES game Ghostbusters (I'm doing an extensive hack, check some screenshots here: <url removed. It's on romhacking dot net>).

Afaik, the game uses 4-bit unsigned little endian samples at a rate of about 3000. It is basically the very same format as the samples on Gauntlet 2 (nes), just slightly different rate. I can take the sample from one game, insert on the other one and it plays fine.
The problem is I want to create a new sample on this format, and nobody can figure out how. The source audio is attached.

There's a discussion about this on nesdev here: http://forums.nesdev.com/viewtopic.php?f=6&t=16823
This topic seems to be useful to the issue, but I didn't get anywhere: http://fullmotionvideo.free.fr/phpBB3/v ... pcm+sample

Any ideas?

edit: urls added, couldn't add before due to I think low post count.
Attachments
newyell.zip
(120.33 KiB) Downloaded 286 times
Last edited by nesrocks on 2017-12-21, 20:11:57, edited 2 times in total.

Post by NewRisingSun »

Why cannot you post URLs? In any case, attached. I had to normalize your .WAV file first, otherwise the sound quality would be even worse --- there's only so much useful signal in 3-bit PCM at 3.3 kHz.
Attachments
newyell2.zip
(179.11 KiB) Downloaded 304 times
Last edited by NewRisingSun on 2017-12-21, 18:43:52, edited 1 time in total.
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

Are you a wizard? That's awesome!

The resulting file is based on value 44, I'm trying to make it based on value 87 like the original, I think that could improve the quality or volume. Haven't fully understood your code yet though.

note: I think I can't post urls because I have low post count.

For reference, I made a wav recording of the three versions.
First, is the original audio. Although it's a bad voice, it is much louder and practically noise free.
The second one is the DPCM version. It uses a different code to play, but it is super low on volume.
The third one is using your method. Crisper and louder than DPCM, but sounds more compressed.
Attachments
newyell.zip
(56.93 KiB) Downloaded 280 times

Post by NewRisingSun »

Oh yeah, slight mistake on my part. Please redownload for a slight sound quality improvement.

Basically, the sound routine used by the game requires four bit unsigned PCM sound data at a rate of 3351.634 Hz, with the low nibble being played first and the high nibble played second. I create such data in two steps:
  1. cnv1.bat uses the SOX utility to normalize the sound wave and convert it to eight bit unsigned PCM sound data at the rate of 3352 Hz, properly downsampling using a good low-pass filter.
  2. Since SOX does not create four bit PCM by itself (to my knowledge); cnv2.exe simply takes the eight bit unsigned PCM sound data produced by the first step, discards the lowest four bits of each sample point, and packs two four bit sample points into one byte. It also pads the entire sample to a length of 0xA00 byte using 0x88 data.
You could get much higher sound quality if you converted the game from CNROM (mapper 3) to GNROM (mapper 66) and use another 32 KiB (or more) for the entire sample. You would have to partially rewrite the game's sound routine for that, and add the bankswitching code. Theoretically, you could go up to 44,100 kHz with seven bits per sample point, although 22 kHz will already sound good enough, as heard in this example (it's a NES variant of a rickrolling video run on actual hardware).

Post by NewRisingSun »

You could get much higher sound quality if you converted the game from CNROM (mapper 3) to GNROM (mapper 66) and use another 32 KiB (or more) for the entire sample. You would have to partially rewrite the game's sound routine for that, and add the bankswitching code.
And here is just that!
Attachments
GHOSTHQ.zip
(56.05 KiB) Downloaded 302 times
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

Holy moly, you rock. That's now as loud as the original sample :D I think I'm satisfied now and can move on with the rest of the hack.

Question:
When you discard the lowest bits is it just like reducing the resolution on an image? Like, the shape is there, just not as defined?

About the suggestion of changing the mapper: in my hacks I really like to do the best work possible with the same mapper used in the original game, so it's easier to compare the differences.
But I'm considering releasing the hack in two distinct versions, one using the same mapper and the other with extended ROM for this sample like you said. edit: you beat me to it, that's amazing, I'm going to credit you in the hack. Prefered alias?

Post by NewRisingSun »

I only have one. What else are you hacking about the game?

Yes, discarding audio bits is like resizing without filtering. (Resizing with filtering would be discarding audio bits with noise shaping. Such would not be feasible for 4-bit samples though.)
Last edited by NewRisingSun on 2017-12-21, 19:57:08, edited 1 time in total.
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

NewRisingSun it is then.

I'm changing quite a lot of things, basically the graphics are meant to be 100% revised, but I'm also improving performance and controls. Not sure yet about touching the game design because I believe that one cannot be saved.

Now I can post links:
http://www.romhacking.net/forum/index.php?topic=24333.0

Post by NewRisingSun »

The original game design was a product of its time, I suppose, but the NES conversion is sub-par even by the standards of the day, so your effort should certainly be worthwhile.

Edit: Will you be restoring (or rather implementing) the "Karaoke" title screen as well?
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

NewRisingSun wrote:Will you be restoring (or rather implementing) the "Karaoke" title screen as well?
I've run out of space for new code, so not really. The little space that I have left I'll use for improving the final boss fight and ending sequence.

I've understood your code for the expanded rom, now I have my hack also expanded, so it works with the hack. I took notes, so I'll continue working using the small version, and when I'm done I'll re-expand to generate both ips files for user preference. Your code was transfering two excess bytes to temporary memory, I think, so I changed the compare to 13 instead of 15. Not that it would be a problem though, it works either way. :beer:

edit: there are a few problems, namely it isn't even starting when testing on the everdrive, and if you reset during the voice playback it will stay on banks 2 and 3, resulting in bad opcodes being run. I'll see what I can do.

Post by NewRisingSun »

I think the Everdrive is initializing the GNROM mapper to the last bank, while most emulators start on the first bank. The solution for both problems would be to set the reset vector in the 32 KiB sample bank to a short routine that sets the GNROM latch to PRG 0 and then jumps to the original reset vector.
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

NewRisingSun wrote:I think the Everdrive is initializing the GNROM mapper to the last bank, while most emulators start on the first bank. The solution for both problems would be to set the reset vector in the 32 KiB sample bank to a short routine that sets the GNROM latch to PRG 0 and then jumps to the original reset vector.
Sounds good, I'll get onto it. I was trying to copy the initialization from a mapper 66 game but that was going nowhere, this sounds simpler.

edit: almost there, got it to work after pressing reset. Virtuanes is a good emulator to test, it's going for bank 3 on power on.
edit2: I see what I did wrong, I didn't copy the routine to temporary memory :D
Last edited by nesrocks on 2017-12-22, 0:21:49, edited 1 time in total.

Post by NewRisingSun »

Rewrote the bankswitching code; runs on all emulators that I have tried as well as my Everdrive N8. I had to saw off ten bytes from the sample to make room for that. I got rid of the in-memory code execution in favor of bankswitching right within the code path.
Attachments
GHOSTHQ.zip
(56.06 KiB) Downloaded 294 times
  • User avatar
  • nesrocks Offline
  • Posts: 9
  • Joined: 2017-04-11, 1:06:47

Post by nesrocks »

NewRisingSun wrote:Rewrote the bankswitching code; runs on all emulators that I have tried as well as my Everdrive N8. I had to saw off ten bytes from the sample to make room for that. I got rid of the in-memory code execution in favor of bankswitching right within the code path.
So smart, I bow before your knowledge. Great work, man! Stupid me copying the code to temporary memory when it could be present on both banks XD
edit: hack adapted, tested on everdrive, all good :D
So, this means I'm going the "three square wave notes" route on the unextended version, so I can use the old sample area for new code for other stuff. I mean, this sounds so good that I'll have the unchanged mapper one just to show that the changed mapper version was just for the voice. And for people who want to use the old board as donor when making repro.
Post Reply