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.
The routine that reads the sample:
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?
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.
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 -----------------------------------------
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?