Hi, I'm interested in programming an NSF player but I have no real experience in sound programming. I know C and C++ and have a decent amount of experience in indie game development.
To start off, I have a decent understanding of what each of registers $4000-$4017 but I have no idea how to turn that information into the sound that comes out of my speakers. Can anyone point me to a good tutorial on the subject? Preferably one geared towards ignorant newbies. If It makes any difference, I'm currently working with Windows 7.
Tutorial on writing a NSF player or 2A03 sound hardware emulator for total newbies is something roughy equal to 'bulding a fusion reactor for newbies', i.e. it is a very specific area with very few people in the world ever interested in doing something like that.
It is difficult to give recommendations on where to start, but I think, wrting a square wave generator, triangle wave generator, and pulse wave (variable duty cycle) generator could be one of such places. Make it render to a file first, then make it send the data to the sound card directly. Make controlable pitch and volume.
Don't forget, NSF player includes a 6502 CPU emulator.
Which of the following is what you want to do?
* You want to produce a file that can be loaded into an emulator or your Nintendo, and play music?
- If so, you should start at famitracker.com
* You want to write a piece of software that can load one of those files, and play it on your computer?
- You should start off by programming a 6502 emulator, and then either use blargg's blip_buf or directly emulate audio at 1.8MHz and use a good resampler.
* You want to build the hardware to load one of those files and play it on your Nintendo?
- Start off with kevtris's implementation and then maybe change things (
http://kevtris.org/Projects/hardnes/ )
People don't really write tutorials for things like this. It's too specific a need. However, there's several open source NSF players you can take a look at to get an understanding. I maintain
NSFPlay. Maybe
NotSoFatso has the easiest to understand source code. Most of the open source NES emulators also play NSF (e.g. FCEUX, Nestopia) since a working NES emulator has really very little to add to support NSF.
That you need to emulate the CPU is probably the most difficult part of making an NSF player; much more difficult than emulating the actual sound-producing bits. There are many open source 6502 emulations though, perhaps you can integrate one that has a suitable license for your project. Once you're over that hurdle, the sound hardware emulation isn't too bad, and it's fairly well documented on the wiki at this point, IMO.
Shiru: Thank you for the explanation. I think you're right about starting with simple waveform generators. I'll see what I can come up with through Google, but so far I'm not having much luck. I'm guessing this sort of thing is a lot more technical than I had anticipated and that finding the correct vocabulary to research this area would be the first step.
Lidnariq: Isn't 1.8MHz a really high sample rate? Isn't CD quality audio 48k Hz or so? Why so much more for such an old machine? What's a resampler?
Rainwarrior: Thanks, I'll take a look through both projects and see if I can't understand that audio components.
1.8MHz is the NES' clock that drives the 2A03 (the NES' CPU and audio chip), so it's the samplerate the audio is natively being generated at. You don't actually need to render the audio at 1.8MHz, but it's the ideal quality level. The noise of the 2A03 in particular is hard to get to sound right without at least ~16x oversampling at 44kHz (you can get a passable result by oversampling just the noise, though).
A lot of things are hard to emulate properly if you don't carefully count the native clock cycles (e.g. PCM audio played back by timed CPU loops), but you don't need to account for the audio output on every single clock. If you look at NotSoFatso you'll see that the audio updates are given a number of CPU clock cycles, and it just emulates that many cycles (at 44kHz this is ~42 CPU cycles per sample) and outputs the current audio state.
Another thing I think is worth to mention is the whole idea of how sound chips works. Generally they simply divide incoming clock frequency, which is pretty high (1.8 MHz in case with APU, as mentioned before) by constant and variable integer values. Resulting output could then go directly to audio output, like square wave - alternating 0 and 1, with value of the volume register used for 1, or drive a waveform generator, like advance pointer in a triangle waveform (16 steps, up 16 down - takes 32 clocks to repeat the waveform), or LFSR for noise generation. This explaination is basically covers up most of the 'theory' behind these things.