NES VGM player

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NES VGM player
by on (#78758)
This is my latest little project after doing the Gameboy VGM player.. an NES version: http://www.youtube.com/watch?v=Tcqk3zLj_qU

As mentioned in the video description I'm using VRC6, so this requires a PowerPak and a modded NES or a Famicom to work. Which is why channel 3 is missing in the video, because my NES isn't modded (yet). All 4 channels work fine in nintendulator and mednafen though.

I still need to work a bit on the timing, and make the screen look less dull, etc.

by on (#78761)
And perhaps you could add a compatibility mode for unmodded NES consoles that runs channel 3 over triangle.

by on (#78782)
With no volume control? That would most likely sound like ****.
And before you start saying that I could do some tricks to alter the volume of the triangle wave; keep in mind that I have to keep an average processing rate of 38 cycles/sample (or 41 for NTSC). :P

One option I considered was to use the DMC channel to simulate a 3rd square wave channel. But to get all the frequency/volume combinations I would need thousands of samples, and I'm not sure if I could switch samples during playback without any noticeable distortion(?).

VRC6 was just the most elegant solution IMO. Most people who develop for or make music for the NES probably has a PowerPak, meaning that they can run ROMs using VRC6. And the modification needed to get expansion audio on an NES is simple enough that I expect that even I can do it despite my crappy soldering skills.

by on (#78788)
Very cool.

by on (#78792)
Are you going to use the VRC6 saw channel for the SN76489 Noise+3rd Pulse waveform?

Btw, If you're going to do the modification of your NES, do not use a 47K resistor. Try to use a 100K potentiometer instead. I made the mistake of using a 47K resistor and it's not enough; so the expansion audio is too loud.

by on (#78794)
Quote:
Are you going to use the VRC6 saw channel for the SN76489 Noise+3rd Pulse waveform?

No, I'm using the first square wave channel of the VRC6. That's already supported by my player - you just can't hear it on my NES since I don't get expansion audio on it.
I guess I could use the other square wave channel for the SN76489 "periodic noise" since the VRC6 supports a 1/16 duty cycle.

Quote:
Btw, If you're going to do the modification of your NES, do not use a 47K resistor. Try to use a 100K potentiometer instead. I made the mistake of using a 47K resistor and it's not enough; so the expansion audio is too loud.

I was thinking of using a 56k resistor. Or is that not enough?

by on (#78795)
I can see how volume manipulation would be easier on the VRC6 pulse, but not sure if it would sound simliar.

Regarding the modification, using a potentiometer would allow you to adjust your values better instead of soldering something in there that isn't perfect. You can also keep the potentiometer underneath your NES in the expansion bay hole so it's flush.

by on (#78796)
Quote:
I can see how volume manipulation would be easier on the VRC6 pulse, but not sure if it would sound simliar.


It should sound the same. The periodic "noise" on the SN76489 is just a square wave with a 1/16 duty cycle (or 1/15 on the colecovision).

by on (#78810)
Here are two demo ROMs, one for PAL and one for NTSC, containing different songs.

nesvgm_pal.nes
nesvgm_ntsc.nes

by on (#78819)
Here are two basic hacks I've done:

PAL
NTSC

The PAL ROM has a song by GreaseMonkey done with his IT2VGM driver.
The NTSC ROM has a song by kulor using the MOD2PSG2 engine.

I've included their unaltered VGMs as well.

It appears that they cut out early. GreaseMonkey's noise pulses are also not in tune. There appears to be noise issues for both of the songs as well. Among other issues.

Hope this helps with the bug testing.

I would include a version of my songs, but some of my VGMs are over 200K.

by on (#78829)
Quote:
It appears that they cut out early.

That's because my player doesn't look at any addresses to determine when to switch to the next bank. I relies on my ROM builder tool to insert VGM command $4B (no parameters) at the end of each 16kB. Command $4B doesn't mean anything in the VGM 1.50 spec, but to my player it means "switch in the next 16kB bank".

Thanks for the songs. They might be of some help.

by on (#78832)
I managed to fix most of the noise problems: kulor_ntsc.nes
It's not possible to get it to sound 100% right, since the 2A03 only has 16 different frequency settings for white noise, while on the SN76489 you can get 1024 by sacrificing the 3rd tone channel.

by on (#78836)
mic_ wrote:
It's not possible to get it to sound 100% right, since the 2A03 only has 16 different frequency settings for white noise, while on the SN76489 you can get 1024 by sacrificing the 3rd tone channel.

Can you alternate between adjacent frequency settings if the period is close to halfway between two existing settings?

by on (#78839)
mic_ wrote:
I managed to fix most of the noise problems: kulor_ntsc.nes
It's not possible to get it to sound 100% right, since the 2A03 only has 16 different frequency settings for white noise, while on the SN76489 you can get 1024 by sacrificing the 3rd tone channel.


Sounding a lot better, except that it seems your non-pitch-referenced periodic noises come out as 2A03 periodic noise instead of octaves of A or 440Hz. A lot of musicians use it as a cheap A too.

As for pitch-driven white noise, I think the only effective option for that is changing the chip to Sunsoft 5B's AY. Too bad it's not properly emulated anywhere yet; especially noise.

by on (#78878)
I got some help with installing a 100kohm potentiometer, so now I've been able to do proper testing on HW.

It's getting closer to being ready for a proper release. The timing is pretty decent now, and I've added NTSC/PAL detection and automatic adjustment of playback speed (though since I only have PAL HW all my NTSC testing has been with Nintendulator).

There's one weird issue left that only happens on HW. Some songs "lock up" at certain positions in the song, and then recover after a short time. My first theory was that it was related to the bank switching, but I can't see why that would be the case, or why only the switch between two specific banks would be a problem. This doesn't happen in Nintendulator or FCEUX, so it's kinda hard to debug.

Youtube video for the current version.

by on (#78880)
mic_: I hear the little lock ups as well. Might be a shot in the dark but you may wish to try a few options... Not worrying about the extra channels, have you tried to see if it "locks up" with GNROM instead? Maybe it has to do with VRC6's mapper code on the PowerPak... Are your mapper files on your card up to date? Do you need NTSC testers with PowerPak?

by on (#78881)
It could be the mapper implementation. I don't know.
I'm using the latest mappers from the retrozone website (1.34).

I can't just switch VRC6 for GNROM since it doesn't use the same mapping scheme. My code relies on the fact that I can switch 16k at $8000 and 8k at $C000, and it'd be non-trivial to change that.

Here's the ROM used for the latest video in case you want to try it on an NTSC console: rushjet1_evilboss2.nes
And here's one where the lockup is really noticeable (shortly after the intro ends): tintin_vgm.nes

by on (#78882)
I'll check it out when I can. I know you can't just swap them, but GNROM is similar enough in how much PRG and CHR that it can handle.

I tested it on hardware. It sounds exactly the same as your recording (except for my expansion channels being louder. ;P)

That's good news because it seems that only the frame before NESVGM bankswitches back to the first pattern/frame/bank that it does the slight hanging as well. It does not hang on any other frame no matter how long it loops.

Edit:

EvilBoss2 VGM

It skips in the VGM as well. Not sure if you have an issue or not.

I imported the VGM into MOD2PSG2 and it appears that if you look at pattern #16 that it was done purposefully.

PSGMOD

Are we talking about the same "locking up" here?

Also regarding the Tintin conversion, I don't notice any sort of locking up whatsoever on my NTSC console.

Here is an MP3 render from hardware.

by on (#78883)
Try the second ROM (tintin_vgm.nes) and you should hear what I mean.

by on (#78884)
Crap, I didn't edit quick enough.

Check my post above. ;)

by on (#78885)
That's really strange. Here's what it sounds like on my console: tintin_pal.mp3

What's your PowerPak ROM/Card version? Mine says 1.00 / 1.34.
Maybe it's a hardware issue. The weird thing is that it only happens in some songs, but it happens at the same spot in those songs all the time.

by on (#78887)
Mine's ROM v1.10 and card v1.34. The newest ROM version is v1.11, but it's only an aesthetic change.

You'll need to have your PowerPak ROM updated by a USB CopyNES. I tried hacking in the code from BunnyBoy's USB CopyNES software to Quietust's CopyNESW (LPT) but I'm not good enough at C to do it.

You might want to ask around on the forum if there is anyone around your area with a USB CopyNES.

Still that might not even be the issue. I'm not sure, mic_.

by on (#78890)
hi

in-game from MasterMind (by me)
Final Take-Off (Afterburner)

i'm sorry

by on (#78908)
B00daW wrote:
Mine's ROM v1.10 and card v1.34. The newest ROM version is v1.11, but it's only an aesthetic change.

You'll need to have your PowerPak ROM updated by a USB CopyNES. I tried hacking in the code from BunnyBoy's USB CopyNES software to Quietust's CopyNESW (LPT) but I'm not good enough at C to do it.

You might want to ask around on the forum if there is anyone around your area with a USB CopyNES.

Still that might not even be the issue. I'm not sure, mic_.


Yeah, it would be nice if someone with the same PowerPak SW versions (boot ROM 1.00 and mappers 1.34) could test the tintin_vgm.nes ROM on their NES. If they don't get the problem, then at least I could rule out any software issue.

Here's the player + ROM builder tool + source code: nesvgm-1.zip

by on (#78945)
Looks like you're ignoring the optional frequency divider part of the VGM header. Good thing the 2A0x has enough lower-octaves to compensate; even though its not really easy to do on SN7- hardware.

Here's an example of Chris Kelly's 1ultra which was included in MOD2PSG2.

A solution to this issue is that you could drop the notes' octaves by 1 to compensate and it should sound fairly accurate.

Btw, do you know of a real way to pull off the 2x frequency divider for a hardware VGM player for GG/SMS? Wouldn't the crystal have to be underclocked? Would it be possible to lag the frequencies in the player routine?

Also, here is an example of a 116K VGM2NES that is a lot of wank that I did.

by on (#78982)
mic_ wrote:
Yeah, it would be nice if someone with the same PowerPak SW versions (boot ROM 1.00 and mappers 1.34) could test the tintin_vgm.nes ROM on their NES. If they don't get the problem, then at least I could rule out any software issue.

I have boot ROM 1.00 and downloaded 1.34 mappers from RetroZone website, and it worked without glitches (PAL NES).

Here's a rather strange (unrelated) thing.. since I had a custom set of mappers on PowerPak prior to downloading 1.34, I renamed the directory to something like POWERPAK-custom (I also had other older versions of the mappers renamed like this) and then extracted 1.34 on the CF in POWERPAK directory... For some strange reason it was showing 1.33B1 as the version at bootup, like it was reading them from the wrong directory. I then went to add an underscore in front of all the mapper dir names and it displayed 1.34. I tried removing the underscores once again and yep, it's reading from the wrong directory again.

Soo.. I guess it's only checking the first 8 characters of the filename, and uses the one which happens to come first in the file system.

by on (#78984)
To be thorough, when I upgrade mappers, I perform a "clean install": I backup all folders except /POWERPAK, reformat, and restore.

by on (#79117)
Seems like the distortion is due to interference from the audio mod. I fiddled around a bit with the wires leading to the potentiometer, and some of the lockups in the Tintin song vanished (though not all of them).

Quote:
Looks like you're ignoring the optional frequency divider part of the VGM header. Good thing the 2A0x has enough lower-octaves to compensate; even though its not really easy to do on SN7- hardware.

Yeah, all my frequency tables are based on an SN76489 clock of 3579545 Hz. But it wouldn't be that hard to make the ROM builder tool overwrite the tables with new values based on the clock setting found in the VGM.

Quote:
Btw, do you know of a real way to pull off the 2x frequency divider for a hardware VGM player for GG/SMS? Wouldn't the crystal have to be underclocked? Would it be possible to lag the frequencies in the player routine?

You could set the tone channel periods to zero to get a constant high output, and do SW-generated square waves by modifying the volume at precise intervals. But I'm sceptical about the possibility of pulling that off for 3 channels simultaneously.

by on (#79174)
Here's an updated version that supports custom SN clock settings between 1 and 7 Mhz: nesvgm-2.zip

I've also added support for NES VGMs, as specified by VGM 1.60. There's an example of such a song included in the archive (ff3_battle).