I wrote a page a while back about the NES Audio.
But, mostly you shouldn’t have to know that much about the sound registers. We are going to use Famitracker to write the music and Famitone 2 v1.15 to play the music. I have been including the famitone code in every example, so that it’s already in place for you. All you have to do is to include the music data file in crt0.s right below music_data:
I’m not the best famitracker musician, so maybe you should watch a tutorial about using it, like this one.
I like this tool chain, but famitone2 has some limitations.
- No volume column.
- Allowed notes are C-1..D-6, Note Cut
- Only Volume, Arpeggio, and Pitch sequences
- All instruments should have a volume envelope assigned
- no Duty sequence
- 64 instruments max
- no fx except Tempo Fxx, Looping backwards Bxx, and ending the frame early D00
- Up to 17 sub songs in a file
Because there is no volume column, you might want to make a few instruments of different max volume.
And a warning, don’t set ROWS = 256. The text2data program won’t work right.
Put every song into the same file, use “module properties” to add a song.
Once everything is done, export a txt file. You need to process this file with famitone2 program text2data.exe. Use the command line, and add the -ca65 switch. I put text2data and the txt file in the same folder, then typed CMD in the address bar, and a command prompt opens. Then I typed
text2data TestMusic3.txt -ca65
and it produced a .s file. This file is then included to the project inside the crt0.s file, right below the music_data label. Our startup code automatically sets a pointer to this file for us.
I wrote 2 songs and imported them into the platformer game.
music_play(0) plays the first song.
music_play(1) plays the second song.
Press “start” to switch between the songs.
The neslib code automatically updates the audio registers to match the song. At the end of the nmi code, FamiToneUpdate is called, once per frame.
If you need to, you can pause the song music_pause(1) and unpause the song music_pause(0). And you can stop the song altogether music_stop().
Oh, and one more side note. I wrote a function that allows you to change the speed of the music with your code. Normally, you could only set the speed inside the famitracker file. But, what if you wanted to speed it up for a boss fight, or slow it down if you are in some stunned state? Well, now you can easily do that with this function…
Lower numbers mean faster, bigger means slower. 6 is the default.
On a side note, there are other music drivers.
Pently, has been used in a few games, and might be good for you if you like to write your music with a sheet music tool. It uses a descriptive language. Music Macro Language (MML) or LilyPond can be used.
ggsound is another options. NESmaker is using it. I am not familiar enough to give details.
The full famitracker driver is another option, but it’s very large, and a bit slower than other drivers. You can get it from shiru’s example file.
Or you could look at cppchriscpp’s example code, which uses it, I think (?).
I also wrote some unofficial updates to famitone. They add a volume column, all notes, and some of the famitracker effects.