NSF Tracks Ripper HELP

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NSF Tracks Ripper HELP
by on (#49612)
Hi,
I want to write a program which can extract each track into a single file from a multi-track NSF file.
I know there is a software in Windows that can do the same thing but I just want to write one myself.
Please let me know if there is any open-source library can help me do that. And any related documents will help too.

Thanks in advance!

by on (#49625)
There is no "Extraction", you just append a fragment of code to do "LDA #xx" at the beginning of the code, then jump to the proper init address. Then you have a NSF identical to the original, except it ignores the user supplied track number, and only plays that one specific track.

by on (#49640)
Thanks for your replay!

I compare the track #1 file riped by [NSF Track Ripper] and the original one. There are some changes confuse me.

1. 00000000AH changes from "13 80"(30592) to "4E 86"(30598). I knew that the value means [init address of data], so it points to the begin of the data in file right? The header's length doesn't change why the value changed?
2. How can I know when a track ends? Is every track have a fix length or Is it ends with something like EOF?
3. How can I know that one track uses some other user supplied tracks? When that happens should I copy the user supplied track's data there?
4. Every file's end are differences. Is that means that there is no specified end format and only header and data.

by on (#49662)
arthurln wrote:
1. 00000000AH changes from "13 80"(30592) to "4E 86"(30598). I knew that the value means [init address of data], so it points to the begin of the data in file right? The header's length doesn't change why the value changed?


0x0A is the init address for what gets run, 0x08 is where the data in the file starts getting put into memory. It's not uncommon for data running later in an NSF to refer to data or run code that's prior to the init code. I really can't understand 0x0A changing on an optimized NSF.

arthurln wrote:
2. How can I know when a track ends? Is every track have a fix length or Is it ends with something like EOF?


It's simply beyond the realm of reason to expect to know when a song ends in an NSF. Data logging is ineffective for this, song part similarity as well. Your only real bet to get all the data is to run it for about 7 minutes and hope you get all the song data.

arthurln wrote:
3. How can I know that one track uses some other user supplied tracks? When that happens should I copy the user supplied track's data there?


To supply a track to an NSF, you'd need to understand the format of the data, compose something in this format, and add it to the game's code. You'd often have to remove an existing track from the set as well.

arthurln wrote:
4. Every file's end are differences. Is that means that there is no specified end format and only header and data.


This is simple. If you optimize data, and remove the unused stuff, you can just cut it off the end. If the last byte in the file is 00, you can remove that byte. Repeat until last byte != 00. When you optimize, any unused data is set to 00.


Beyond answering specific questions, I should mention that optimizing single songs isn't very useful. Separation of songs from an NSF can go wrong. Space used by an NSF increases as you copy data with required null data in it, with this null data duplicated across several NSF files. If you're desperate to have individual tracks, it can be done with NotsoFatso or even NEZPlug, I think. For NotsoFatso, right-click the file in the winamp playlist you want as single-track entries, go to the 'View File Info' option, then 'Shadow -> Winamp' for a playlist of the nsf in winamp, or 'Shadow -> File' to export a playlist you can play for individual tracks.

Either way, do as you wish. I just see a way around this if I was interested in having some individual-track playlists.
PSF
by on (#49668)
Or handle it like PSF does:
  1. Define a new format .mininsf that lists the filename of a .nsf file, track number, and length of one track.
  2. Change NSF players to use .mininsf, loading the .nsf in much the same way that PSF players load the .psflib.
  3. In each rip, add a set of .mininsf files, one for each track.

by on (#49670)
Thanks a lot for all your help and I've almost finish the the application except the tracks extraction part.
It is writen in java and I will make it open source on google code later.

by on (#49671)
I really have little knowledge on this field.

Thanks a lot to ugetab but I can't understand what you say.
Thanks to tepples and I will try PSF way later.

My program is basically read the file and handle the bytes. And I still can't solve the problems I've posted before. I do a lot of search but I can't find any documents that can describe the data format. If anyone have some useful documents or source code please mail it to me(lsuang at gmail.com).

Thanks in advance!

by on (#49672)
Quote:
I do a lot of search but I can't find any documents that can describe the data format. If anyone have some useful documents or source code please mail it to me(lsuang at gmail.com).

http://www.tripoint.org/kevtris/nes/nsfspec.txt

There is no format. What follows after the 128-byte header is a NES program that contains the code and data needed to play all the songs in that NSF. What the code and data looks like depends on who wrote it, so it will differ a lot between games made by different companies (and sometimes between different games made by the same company).
Like someone suggested early on in the thread, if you want to make a single-song NSF from an existing NSF the only universal way to do so is to inject a machine code sequence at the init address that sets the A and X registers to the song number that you want.