Create 4-bit unsigned little endian PCM samples?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Create 4-bit unsigned little endian PCM samples?
by on (#210008)
Can someone help me generate a decent ghostbusters yell pcm audio to replace the original nes version? I'm in the process of hacking this game and I thought it would be cool to have that yell replaced with one of the yells from the official song. There is a version of that song with vocals only and I've isolated one of the yells in .wav format, but I'm having a hard time generating a decent pcm file. Maybe the game's code for this is bad too?

I tried famitracker and NESPCM but the game plays a screeching sound along with the yell. The game has $94E bytes reserved for this sample, and it isn't aligned, but somehow it works. The smaller the new sound the better so I can insert more code for the ending, etc. Ultimately if it can't sound good I'd just remove it altogether for the free space, but I was hoping to keep the feature...

The original sample is located at 0x3DC2-0x470F.
The JSR that plays the sample is at 0x331C.
I think you can adjust playback rate by editting the 0x3343 byte.

I have looked into tutorials and examples (there aren't many), and honestly it all sounds like alien language to me. pseudo explanation: "Hey, just do 1-bit downsample every other 4 bytes from deamplified 33 hz raw riff wav, how hard can it be?". I totally don't get it. :cry:

The routine that reads the sample:

Code:
ghostbussteerrs:
 00:B30C:A9 FF     LDA #$FF
 00:B30E:8D 15 40  STA $4015 = #$00
 00:B311:A9 B2     LDA #$B2
 00:B313:85 F0     STA $00F0 = #$00
 00:B315:A9 BD     LDA #$BD
 00:B317:85 F1     STA $00F1 = #$00
 00:B319:A0 00     LDY #$00
pcm_loop1:
 00:B31B:B1 F0     LDA ($F0),Y @ $BDB2 = #$77
 00:B31D:29 0F     AND #$0F
 00:B31F:0A        ASL
 00:B320:0A        ASL
 00:B321:0A        ASL
 00:B322:8D 11 40  STA $4011 = #$00
 00:B325:A2 68     LDX #$68     ; you can adjust this to change rate?
pcm_loop2:
 00:B327:CA        DEX
 00:B328:D0 FD     BNE pcm_loop2
 00:B32A:B1 F0     LDA ($F0),Y @ $BDB2 = #$77
 00:B32C:29 F0     AND #$F0
 00:B32E:4A        LSR
 00:B32F:8D 11 40  STA $4011 = #$00
 00:B332:A2 65     LDX #$65    ; this can also be adjusted
pcm_loop3:
 00:B334:CA        DEX
 00:B335:D0 FD     BNE pcm_loop3
 00:B337:E6 F0     INC $00F0 = #$00
 00:B339:D0 E0     BNE pcm_loop1
 00:B33B:E6 F1     INC $00F1 = #$00
 00:B33D:A9 C7     LDA #$C7       ; this determines how long the sample is to be read from the rom
 00:B33F:C5 F1     CMP $00F1 = #$00
 00:B341:D0 D8     BNE pcm_loop1
 00:B343:60        RTS -----------------------------------------


I don't totally understand it, but looking at some PCM asm examples, it seems like once you start playing it goes automatically, but this routine is constantly resetting the thing for each byte read?
Re: "Ghostbusters!" PCM little help needed
by on (#210027)
The original PCM sample (I've looked at it) is unsigned 4-bit, little-endian. It plays at a very low frequency (between 3 and 4 khz), which is probably much of why it sounds so bad. Part of the sample isn't played at the end, which has a click sound, which is why it sounds like "Ghostbuster". Hope that helps.
Re: "Ghostbusters!" PCM little help needed
by on (#210028)
Is there a way to free up enough space elsewhere in the ROM? How much PRG and CHR ROM is unused?
Re: "Ghostbusters!" PCM little help needed
by on (#210029)
@SuperWill24:
So, you feel like in this little space ($94E bytes) there wouldn't be a chance to make a better sounding PCM?

@tepples:
There's $77D unused bytes on the PRG (scattered throughout), and I need to add some code still for the ending.
On the CHR that is "loaded" at the title screen there are just a handful of free tiles, but when it goes to the disclaimer it changes CHR, so the start button can be pressed on either time. Do you think it could be loaded from CHR? In this case the screen would need to go blank and switch to the appropriate one when playing the sound. If this is possible I'm ok with this solution. edit: just checked, the CHR has just $600 bytes free, I thought it'd be more. That's not much help.

As a principle I didn't really want to extend the rom or change mappers, I just want to do the best I could with exactly the same tech as the original game.

The music though I haven't touched yet, and it uses 3 kilobytes (it's a 3 minutes long song). It could be rewritten to optimize and reuse modular sections that are looped. As it is they are just copied over many times. This could free up space. This will be a lot of work, and I'm leaving it for later.
Re: "Ghostbusters!" PCM little help needed
by on (#210034)
That assembler these using?

Always I wanted a game of ghostbuster filmation :P
Re: "Ghostbusters!" PCM little help needed
by on (#210038)
I don't understand your first sentence.
Yeah, I love that other ghostbusters, but the chorus where they sing "let's gooo, ghostbusters!" would take a lot more rom space :)

The file is nice, but I kind of really need the data to be a lot smaller. The sample data must be smaller than $94E bytes...
Re: "Ghostbusters!" PCM little help needed
by on (#210052)
This archive weighs much less
Re: "Ghostbusters!" PCM little help needed
by on (#210053)
I wonder if you could get better quality audio from that amount of space by making it a DPCM sample. Granted you'd have to move a lot of data around to put the sample past $C000, since you can't really rely on the DPCM unit's wrap behavior (Starting at $FFC0 will wrap back to $8000 instead of $C000 if you play >=4*16+1 bytes)
Re: "Ghostbusters!" PCM little help needed
by on (#210056)
Hummm I don't know, but the game doesn't like the format (it plays a very garbled sound). I tried using famitracker and tepple's 81.exe converter, but I guess the result isn't 4-bit unsigned? How would I go about making it so?
Re: "Ghostbusters!" PCM little help needed
by on (#210068)
You can share the original sound ?
Re: "Ghostbusters!" PCM little help needed
by on (#210070)
Sure! Here you go (file attached).

Here's a small preview of it:
Code:
77 88 AA 9A 78 67 66 55 66 76 65 76 76 77 87 88
87 89 97 98 88 99 98 98 89 88 89 77 89 7A 76 98
77 87 6B 67 87 78 77 B7 66 76 68 67 98 78 75 87
77 77 9A 67 77 78 77 B7 66 77 78 76 98 69 76 79
59 67 6C 66 79 87 77 C9 65 A5 A7 75 D6 58 76 78
68 77 9A 65 96 87 76 D9 FF FF FF FF C6 58 76 78
5A 76 6E 56 7B 67 57 CD 63 97 A7 64 E7 58 A5 77
68 A5 4D 57 7A 5A 57 9D 64 87 98 55 D7 54 B6 89
66 B5 8A 65 99 88 56 AB 74 99 98 55 D6 55 A7 89
58 75 4C 77 89 69 55 8D 75 8A 87 56 D7 74 A7 87
78 74 4C 67 7A 59 48 8D 84 87 97 57 D7 75 98 77
Re: "Ghostbusters!" PCM little help needed
by on (#210080)
nesrocks wrote:
Hummm I don't know, but the game doesn't like the format (it plays a very garbled sound). I tried using famitracker and tepple's 81.exe converter, but I guess the result isn't 4-bit unsigned? How would I go about making it so?


If I recall correctly, tepples's 81.exe converter converts to the NES 1-bit DPCM format, not 4-bit unsigned. Here's my method to convert:

1. Open the wav file in Audacity (or any other sufficient audio editor). Resample to the frequency to whatever extremely low frequency the game uses, and make sure it's mono as well.
2. Export to a RAW file. In Audacity, set the type to "Other uncompressed files" and then go "Options" and set the properties to "Raw (headerless)" and the encoding to "Unsigned 8-bit PCM".
3. Run the attached program through DOSBox to convert the raw sample file you have to a 4-bit PCM file (it has the extension .GBW in this program).
4. However, the resulting file is big-endian, not little-endian, so you'll need to byteswap the file so it can be little-endian. I am not sure which program can do this.
5. Replace the original sample with the resulting new sample.

I'm also kind of glad to see a topic like this appear, since currently I've been interested in sample ripping from old consoles like the NES.
Re: "Ghostbusters!" PCM little help needed
by on (#210086)
za909 wrote:
I wonder if you could get better quality audio from that amount of space by making it a DPCM sample. Granted you'd have to move a lot of data around to put the sample past $C000, since you can't really rely on the DPCM unit's wrap behavior (Starting at $FFC0 will wrap back to $8000 instead of $C000 if you play >=4*16+1 bytes)


Wait, the sample isn't DPCM? Any reason not to do that? Are they playing it in a way that actually conserves space compared to regular DMC sample playback?
The sound quality is definitely terrible as it is.
Re: "Ghostbusters!" PCM little help needed
by on (#210119)
I'm having a hard time converting big to little endian. Could by any chance the code that reads the data be changed to accept big endian instead?
In our 4-bit case does this mean that for every byte the order of each 4 bits group must be inversed?

@Sumez: I thought dpcm and pcm were the same thing, I'm sure I read somewhere in these forums that they are just names for the same thing. They aren't?
Re: "Ghostbusters!" PCM little help needed
by on (#210136)
DPCM means "differential pulse code modulation" because it stores the difference between one sample and the next. Sometimes it's referred to as "delta pulse code modulation" using a Greek letter Δ that often means difference between adjacent values in a sequence. In the NES scene, unqualified DPCM has a very specific meaning: the format accepted by the APU's waveform playback unit at $4010-$4013, a 1-bit little-endian DPCM with a 64-step range.
Re: "Ghostbusters!" PCM little help needed
by on (#210143)
In more simple terms, DPCM samples on NES hardware allows the APU to play the sound on its own without much involvement from the CPU, which makes it much more viable to use during actual gameplay, but the sound quality is very limited compared to what you can do with pure PCM playback. Considering how terrible the "ghost buster!" sample sounds in that game, I'm surprised it's not DPCM.
Re: "Ghostbusters!" PCM little help needed
by on (#210145)
Sumez wrote:
Considering how terrible the "ghost buster!" sample sounds in that game, I'm surprised it's not DPCM.

I'm surprised as well.
Re: "Ghostbusters!" PCM little help needed
by on (#210148)
Okay... I'm gonna try replacing the code that plays it for a more standard code then. Luckly for me DPCM can be used because the original sample is partially located at 0xC000, with $700 of its bytes being after 0xC000. So I can instantly have a $700 bytes long dpcm sample to test without having to move anything around.

Instantly, I have a question. Can a new song use this very same sample during its playpack? You know, at the right moments in the song.
Re: "Ghostbusters!" PCM little help needed
by on (#210151)
nesrocks wrote:
Can a new song use this very same sample during its playpack? You know, at the right moments in the song.

Well, of course it can. However, I don't think Ghostbusters' sound engine supports it.
Re: "Ghostbusters!" PCM little help needed
by on (#210152)
I got 1-bit dpcm working! My sample sounds pretty compressed though. I replaced the code for sample playback using tepples 81ex.nes example.

Bregalad wrote:
Well, of course it can. However, I don't think Ghostbusters' sound engine supports it.

Humm yeah okay. The engine supports the noise channel for music, but the noise channel data is just a 00. At least that can be used.
Re: "Ghostbusters!" PCM little help needed
by on (#210153)
I can take an educated guess why they didn't use the shouting sample from the Ray Parker Jr. song in the game.

Compare the scream in Ghostbusters for NES (video) to the same scream in the C64 version (video). Notice that the C64 scream is longer and clearer. This is because it uses a much more efficient audio codec by Forrest Mozer called ESS MX, the same used in Impossible Mission for C64 ("another visitor") and Mito Koumon for Famicom (video). I imagine the NES port team didn't want to spend the extra bucks licensing this codec for the NES version.

The one drawback of ESS MX is that it doesn't handle anything other than a single voice. ESS MX won't handle a crowd shouting because it works based on repeating short wavetable segments one period long, and shouting isn't nearly as periodic. And I imagine they wanted the same audio on all platforms, as licensing the sample from Arista Records just for the NES version would also be more expensive.
Re: "Ghostbusters!" PCM little help needed
by on (#210155)
All of that may be true, but personally I think it's just because this game was made by interns and they used the cheapest quickest solution they could get working.

edit: the licensing thing on the other hand I agree you must be 100% spot on.
Re: "Ghostbusters!" PCM little help needed
by on (#210158)
Yeah.... Ghostbusters 1 on NES is a pretty classic example of "here's a lucrative movie license, just put whatever out so we can make money on it, I don't care what it is"
Re: "Ghostbusters!" PCM little help needed
by on (#210159)
@nesrocks I want to see the version that these doing of ghostbuster
Re: "Ghostbusters!" PCM little help needed
by on (#210160)
I'm going to free a little more space so I can have $7A0 bytes instead of $700 and then I'll share an ips. That ok? In fact, I think that if I spend a little more time I can get $9F0 free for the sample.
Re: "Ghostbusters!" PCM little help needed
by on (#210183)
WOW!! :shock:
Far better than the original!!
Thanks, and keep the good work!!
Re: "Ghostbusters!" PCM little help needed
by on (#210477)
After trying everything I'm ready to give up and remove it altogether. Maybe even replace it with 3 notes, like the attached file. The reason for this is that the dpcm sample sounds a lot lower on volume compared to the rest of the game (and the original 4-bit PCM sample).

edit: gauntlet 2 has exactly the same format as the original game, with a faster rate. Now when you press start in a version of ghostbusters only I have, it says "WELCOME WARRIOR", loud and clear. How can we generate new samples on this format?

edit2: when I follow these instructions I can make a sound that is like static noise but it has the same rhythm as the ghostbusters yell.
http://fullmotionvideo.free.fr/phpBB3/v ... f=1&t=1487

You can find Kaja's tools here https://sites.google.com/site/kajapon/pmd

edit3: huge progress, I'm calling it solved: http://vgmrips.net/forum/viewtopic.php? ... 9493#p9493