UNIX Command-line NSF

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
UNIX Command-line NSF
by on (#156504)
This is my idea, a emulator that play NSF using UNIX-pipes, you can have one program to emulate the CPU and enough of the sound stuff to know how to read back and do DPCM (and MMC5 multiplication registers, and so on) and just output the register writes being made, another program emulates the APU (and expansion audio) by using the writes that are output to generate the audio data, you can do like:
Code:
runnsf -a 0 -x 0 < song.nsf | play2a03 -f S16_LE -r 44100 | aplay -t raw -f S16_LE -r 44100


I might write such program, or only one of them, or someone else, or else I don't know. What is your opinion of such things please?
Re: UNIX Command-line NSF
by on (#156516)
That's certainly doable, but I have to ask why. Considering that each of the two programs would be more or less useless without the other, what would you gain by seperating them?
Re: UNIX Command-line NSF
by on (#156522)
One advantage is that you can send the audio output to the NES through the serial port. I've tried it before, it was pretty much how I learned C, by hacking it into Festalon and FCEU. The NES probably needs to buffer a few frames worth of data, I figure the PC-side should maybe send numbered packets and the NES/audio side an ack/nak and packet number response or something, but it worked pretty well with even no buffering at all, if the thread was set to highest priority. But more recently I have started over on this type of program. I started out with fake6502 by Miker00lz, it's set up to communicate over the COM port, but right now all the program does is print some stats, output like this:
Code:
Loading NSF player program
Loading test.nsf

Guardian Legend
Miyamo Shant
1988 Irem/Compile

NSF init finished.  367 instructions.  CPU: 1215 cycles  PPU: 10.7 lines
NSF playing... (ESC to quit)
NSF play stopped.

Max CPU: 3512 cycles  Max PPU: 30.90 lines
Average CPU: 1878 cycles  Average PPU: 16.52 lines
4772291 frames played - 1325 minute(s), 11 second(s)



I don't know if it's any use at all, but I've attached the sources for what it is. I'm wanting to get this thing working eventually, I've just been spending more time on making a better serial adapter first, synchronous and free of DPCM clock glitches. Asynchronous communication has a separate problem with using DPCM because it steals cycles, but I remember blargg wrote an NSF player that adjusted it's timing to work, that was pretty cool.
Re: UNIX Command-line NSF
by on (#156525)
One tenet of UNIX philosophy is that each program should do one thing and do it well. What you have here is one program that converts NSF into what some call a "logged format" (like VGM), another utility that converts logged format into a sample stream, and a third that sends a sample stream to an output device.

It's especially useful to separate the last step so that instead of playing the samples, you can pipe them into something else. This could be a WAV, FLAC, MP3, Vorbis, or Opus encoder, an audio/video encoder if you're using an NSF soundtrack for a silent film, or even a game so that NSF rendering can happen in its own thread that feeds your game's mixer.
Re: UNIX Command-line NSF
by on (#157557)
Honestly, this is something that I've been googling around for for a few days. I thought it would be neat to try to do some algorithmic based composition. I (naively) thought that the NSF format was something more like MIDI.
Re: UNIX Command-line NSF
by on (#157604)
There's the VGM format, which does support the 2A03's sound capabilities, and is a register write log, similar to MIDI.
Re: UNIX Command-line NSF
by on (#157616)
hippadrone wrote:
I (naively) thought that the NSF format was something more like MIDI.

That'd be an interesting project: a MIDI to NSF converter. Then you could stick another pipe on the front. "We need to go deeper."
Re: UNIX Command-line NSF
by on (#157631)
Hmmm, the vgm format looks interesting, I'll have to check it out. Thanks! Is there a lot of music out there in the format? My full plan was to train an ai agent (probably mess around with some neural nets) on a corpus of music and then use that net to generate new music.
Re: UNIX Command-line NSF
by on (#157641)
There's quite a lot of VGM music, but not a lot of NES VGM music. Most NES music is in the NSF format, it is overwhelmingly the more popular format. Edit: While NSF is the more popular format, there is actually a fair amount of NES music in VGM format, apparently: VGMRips NES packs

You could write an NSF to VGM converter: an existing NSF player could be modified to produce logs of the register writes and timings, which would let you automatically produce VGM files out of NSF files, if you needed such a thing. (A VGM to NSF converter is also possible, I suppose.)

NSFPlay has a logging capability that will dump register writes as a text file for you, which you could process into a VGM.
Re: UNIX Command-line NSF
by on (#157646)
rainwarrior wrote:
You could write an NSF to VGM converter: an existing NSF player could be modified to produce logs of the register writes and timings, which would let you automatically produce VGM files out of NSF files, if you needed such a thing. (A VGM to NSF converter is also possible, I suppose.)

When I worked with (a modded version of) FamiTone, its tool for creating sound effects first turned an NSF into a write log (like NSF to VGM) and then processed the write log into a sound effect definition for inclusion in an program using FamiTone (like VGM to NSF). An NSF round-tripped to VGM and back will never be as small as the original, except in a few special cases with a converter specially designed to detect envelopes of instruments. It's like the difference between creating level with individual tiles and the object-based level format of a Super Mario game.
Re: UNIX Command-line NSF
by on (#157652)
When I wanted to test my emulator's implementation of the Sunsoft 5B, I converted some Atari ST .YM music (logged format) to NSF so that I could try some music that used the envelope and noise features of the chip.

Some people have converted to NSF and back as a means of obfuscation against an NSF decompiler. Obviously the size gets a lot bigger, but the maximum NSF size is 1 MB, and in "normal" music formats like MP3 1 MB isn't a whole lot of music anyway, so I don't think the size bloat is a big deal to a lot of people. The most important size limit is usually the PowerPak 252k limit.
Re: UNIX Command-line NSF
by on (#161233)
Thank you Memblers for starting on this.

If I get time to sit down with it, I might add these:
  • More robust argv parsing
  • Histogram of CPU use, so I can better develop a strategy to minimize the worst case
  • Logging of the program counter during the 100 longest frames
  • Time limiting, so that each song gets played through twice but not two thousand times
  • A breakpoint that stops execution at the end of the frame once a certain PC has been seen twice, so I can have it stop when the song has hit the looping opcode twice
  • Logging to frame-, scanline-, or sample-accurate VGM or similar format, so I can pipe it into a VGM to WAV renderer or VGM to serial sender (see "UNIX philosophy" above)

If someone else gets time to sit down with it, I encourage you to beat me to it.
Re: UNIX Command-line NSF
by on (#161459)
VGM isn't really a streamable format, because a header is required where length and so on are known ahead of time. You may use a stream format instead, which may not require a header with length information. Another thing is that VGM does not support all sound chips of NSF.