Filling out the fields in the SPC file format

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Filling out the fields in the SPC file format

Post by tepples »

I'm working on a ca65 project template for SPCs assembled directly from source code. An early version is included with my LoROM project template. For example, a homebrew game developer could use this to offer a clean SPC rip of the game's soundtrack. But I don't know how to set up some of the fields listed in SPC and RSN File Format.

$24: "Version Minor (i.e. 30)"
This is decimal, correct?

$27: "A"
Is there a way to specify that all SPCs in a set are identical except for one register value without paying for WinRAR and making an RSN with multiple copies of the SPC that differ only by $27 (A) to select a song? It might be possible by including a Python script that duplicates the ROM, but the vast majority who uses Microsoft Windows as a primary operating system do not have a copy of Python installed. Should a set include a PowerShell script for Windows users and a Python script for everyone else?

$2E: "Song Title"
Are text fields like this space-padded or NUL-padded?

$6E: "Name of Dumper"
What goes here if the SPC was created by the artist?

$7E: "Comments"
What goes here?

$9E (binary format): "Date SPC was Dumped (YYYYMMDD)"
How are the 4 bytes allocated? Is it BCD or something else? Or is the "text format" more compatible?

$A9 (text format): "Number of Seconds to Play Song before Fading Out"
Is this zero-padded on the left, space-padded on the left, space-padded on the right, or NUL-padded on the right? Also, nobody needs more than 16 minutes and 39 seconds in the same way that nobody needs more than 64K.

$A9 (binary format): "Number of Seconds to Play Song before Fading Out"
I'm assuming little endian. Am I right?

$D2 (text format), $D1 (binary format): "Emulator used to dump SPC (0 = Unknown, 1 = ZSNES, 2 = Snes9x)"
Should SPCs assembled from source just use 0?

$101C0: "Extra RAM (Memory Region used when the IPL ROM region is set to read-only)"
What is this? Is this supposed to be a copy of the IPL ROM, or the memory "behind" the IPL ROM? Should the IPL ROM be stored at $100C0 in the file ($FFC0 within the RAM segment)? For songs that don't themselves call the IPL ROM other than to "quit", how critical is it that the data stored here match the actual IPL ROM?

Why are the metadata fields called ID666 anyway? I understand ID<number> because of ID3, a metadata extension to MP3 audio files. But why the 666?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Filling out the fields in the SPC file format

Post by Bregalad »

For the text files I'd recomend to leave all them to 0x00, this is valid, as ID66 is not mandaotry in the SPC standard.
or the memory "behind" the IPL ROM?
My understanding is that if the IPL ROM is enabled at the time of the dump, it is present at 0x100c0 and the memory "behind" it at 0x101c0. Buf it IPL ROM is disabled at the time of the dump, the memory "behind" it is naturally present at 0x100c0. This feature is absolutely ridiculous and useless, as storing the IPL ROM in SPC files makes absolutely no sense whatsoever. I don't even know how many SPC players supports this distinction, but I wouldn't be surprised if each one behaves in a completely different way.
User avatar
whicker
Posts: 228
Joined: Sun Dec 13, 2009 11:37 am
Location: Wisconsin

Re: Filling out the fields in the SPC file format

Post by whicker »

The point of storing the IPL rom was in case anything referenced it accidentally or from cleverness. I can't be 100% sure because I've never done audio programming, but it might be necessary because of the (poorly named) concept of SPC Rape, sometimes called Square Rape. Executing data as code, or code as sound data...

For example, from what I can remember the wind noise is done this way. Sounded absolutely ridiculous until the audio module was almost perfectly emulated.


Tepples: maybe try asking kode54 of foobar2000 about these nuiances? He's definitely still around.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Filling out the fields in the SPC file format

Post by Bregalad »

whicker wrote:Executing data as code, or code as sound data...

For example, from what I can remember the wind noise is done this way. Sounded absolutely ridiculous until the audio module was almost perfectly emulated.
No. The FF6's and Chrono Triggers' wind noise who-was-sounding-ridiculous-in-old-emulators-and-spc-players is done with a pseudo-white noise sample, which is made by decoding a loud sine-like wave and abusing the BRR decoding hardware's behaviour on overflow into an unstable chaotic number sequence generator. This has the enormous advantage of storing a long pseudo-random sequence using only a very short amount of memory.

1) It has nothing to do with executing data as code or code as data
2) It has nothing to do with IPL ROM
3) Not only Square, but also Capcom and other companies used this technique
4) Whoever came with the "rape" name is retarded, it's the first time I hear about this
User avatar
whicker
Posts: 228
Joined: Sun Dec 13, 2009 11:37 am
Location: Wisconsin

Re: Filling out the fields in the SPC file format

Post by whicker »

Alright,

But we're back to: Is it theoretically possible to write a sound program that, in order to function correctly, requires the IPL ROM data to be bit perfect and immune to writes?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Filling out the fields in the SPC file format

Post by Bregalad »

Yes ?

But that doesn't mean the IPL ROM has to be stored in the .spc file, it should be stored in the replayer itself.
mic_
Posts: 922
Joined: Thu Oct 05, 2006 6:29 am

Re: Filling out the fields in the SPC file format

Post by mic_ »

$24: "Version Minor (i.e. 30)"
This is decimal, correct?
I write decimal 30 when I create SPC files.
$2E: "Song Title"
Are text fields like this space-padded or NUL-padded?
I NUL-pad.
$6E: "Name of Dumper"
What goes here if the SPC was created by the artist?
The name of the artist?
$7E: "Comments"
What goes here?
Anything you like. I suppose you could fill it with NUL-bytes if you want to.
$9E (binary format): "Date SPC was Dumped (YYYYMMDD)"
How are the 4 bytes allocated? Is it BCD or something else? Or is the "text format" more compatible?
SNESAmp does the following for binary ID666 tags:

Code: Select all

y = *(u16*)(&spc.date[2]);
m = *(u8*)(&spc.date[1]);
d = *(u8*)(&spc.date[0]);
Where spc.date contains the actual 4 bytes from the tag.
$A9 (text format): "Number of Seconds to Play Song before Fading Out"
Is this zero-padded on the left, space-padded on the left, space-padded on the right, or NUL-padded on the right? Also, nobody needs more than 16 minutes and 39 seconds in the same way that nobody needs more than 64K.
SPCAmp calls atoi() on the string, so I assume NUL-padded on the right.
$A9 (binary format): "Number of Seconds to Play Song before Fading Out"
I'm assuming little endian. Am I right?
This is what SPCAmp does:

Code: Select all

i = *(u16*)(songStr);
if (i > 959) i = 959;
Where songStr contains the 3 bytes from the tag.
$D2 (text format), $D1 (binary format): "Emulator used to dump SPC (0 = Unknown, 1 = ZSNES, 2 = Snes9x)"
Should SPCs assembled from source just use 0?
That's what I do. But the addendum for v0.31 of the SPC format spec says that "The current Win32 version of ZSNES saves binary SPC files; SNES9x saves in text format". So you might want to keep that in mind to make it easier for players to detect the ID666 format you're using.
$101C0: "Extra RAM (Memory Region used when the IPL ROM region is set to read-only)"
What is this? Is this supposed to be a copy of the IPL ROM, or the memory "behind" the IPL ROM? Should the IPL ROM be stored at $100C0 in the file ($FFC0 within the RAM segment)? For songs that don't themselves call the IPL ROM other than to "quit", how critical is it that the data stored here match the actual IPL ROM?
I just fill this area with zero-bytes.
Post Reply